Spring Boot应用中实现基于JWT的登录拦截器,以保证未登录用户无法访问指定的页面

目录

一、配置拦截器进行登录校验

[1. 在config层设置拦截器](#1. 在config层设置拦截器)

[2. 实现LoginInterceptor拦截器](#2. 实现LoginInterceptor拦截器)

[3. 创建JWT工具类](#3. 创建JWT工具类)

[4. 在登录时创建JWT并存入Cookie](#4. 在登录时创建JWT并存入Cookie)

二、配置JWT依赖和环境

[1. 添加JWT依赖](#1. 添加JWT依赖)

[2. 配置JWT环境](#2. 配置JWT环境)


本篇博客将为大家介绍了如何在Spring Boot应用中实现基于JWT的登录拦截器,以保证未登录用户无法访问指定的页面。

一、配置拦截器进行登录校验

1. 在config层设置拦截器

我们首先在config层创建一个配置类,用来设置需要拦截的页面。在Spring Boot中,我们可以通过实现WebMvcConfigurer接口来配置拦截器。

创建LoginConfig类:
java 复制代码
import com.bim.bimbookshop.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 登录拦截配置类
 */
@Configuration   // 表明这个是配置类
public class LoginConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    /**
     * 配置拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)  // 添加拦截器
                 .addPathPatterns("/**")  // 配置拦截路径
                 .excludePathPatterns("/login/**", "/static/**", "/templates/**"); // 配置排除路径
    }
}

这里的addPathPatterns("/**")表示拦截所有路径,而excludePathPatterns用于排除登录、注册等静态资源的路径。例如,/login/**表示排除所有与登录相关的请求。

2. 实现LoginInterceptor拦截器

接下来,我们需要在interceptor层创建一个拦截器类,用来判断用户是否已登录。

创建LoginInterceptor类:
java 复制代码
import com.bim.bimbookshop.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 登录拦截器
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    /**
     * 过滤除登录请求外的其他请求
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if ("token".equals(cookie.getName())) {
                    String userToken = cookie.getValue();
                    if (!StringUtils.hasText(userToken)) {
                        response.sendError(HttpServletResponse.SC_UNAUTHORIZED); // 未认证
                    }
                    // 解析token并验证
                    try {
                        Claims claims = JwtUtil.parseJWT(userToken);
                        claims.getSubject();  // 如果解析成功,代表用户已登录
                    } catch (Exception e) {
                        System.out.println("Token信息出错");
                        return false; // 如果token无效,返回false,阻止访问
                    }
                    return true;  // 放行
                }
            }
        }
        return false;  // 如果没有找到token,则返回false,拒绝访问
    }
}

3. 创建JWT工具类

我们需要一个工具类来生成和解析JWT。这个类会提供生成JWT的功能,并在拦截器中进行解析和验证。

创建JwtUtil类:
java 复制代码
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;

/**
 * JWT工具类
 */
public class JwtUtil {

    // 设置过期时间,单位为毫秒
    public static final Long JWT_TTL = 60 * 60 * 1000L; // 1小时
    public static final String JWT_KEY = "qcby";  // 密钥

    /**
     * 创建token
     * @param subject 主题,可以是用户的ID或其他信息
     * @return JWT token
     */
    public static String createJWT(String subject) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        long expMillis = nowMillis + JWT_TTL;
        Date expDate = new Date(expMillis);
        SecretKey secretKey = generalKey();

        JwtBuilder builder = Jwts.builder()
                .setId(UUID.randomUUID().toString())  // 唯一的ID
                .setSubject(subject)  // 主题
                .setIssuer("wd")  // 签发者
                .setIssuedAt(now)  // 签发时间
                .signWith(signatureAlgorithm, secretKey)  // 使用HS256算法进行加密
                .setExpiration(expDate);  // 设置过期时间

        return builder.compact();
    }

    /**
     * 生成加密后的秘钥
     * @return SecretKey
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.getDecoder().decode(JWT_KEY);
        return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
    }

    /**
     * 解析JWT
     * @param jwt token
     * @return Claims
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }
}

4. 在登录时创建JWT并存入Cookie

在用户登录成功后,我们会生成一个JWT,并将其保存到浏览器的Cookie中。这样,用户下次访问时,可以通过解析Cookie中的token来验证登录状态。

登录方法:
java 复制代码
public ResponseResult Login(Login login, HttpServletResponse response) {
    // 登录验证逻辑

    // 登录成功后,根据用户ID生成JWT
    String token = this.jwtUtil.createJWT(String.valueOf(user.getUserId()));

    // 将token存入Cookie中
    Cookie cookie = new Cookie("token", token);
    cookie.setPath("/");  // 将cookie作用域设置为整个网站
    cookie.setMaxAge(36000);  // 设置cookie过期时间为10小时
    response.addCookie(cookie);  // 将cookie添加到响应中

    return new ResponseResult("登录成功");
}

二、配置JWT依赖和环境

1. 添加JWT依赖

为了能够使用JWT库,我们需要在pom.xml中添加依赖。

java 复制代码
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

2. 配置JWT环境

我们可以在application.ymlapplication.properties中配置JWT相关的参数,例如过期时间、密钥等。

java 复制代码
spring:
    ...
jwt:
  secret: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4K67DMlSPXbgG0MPp0gH
  expire: 86400000  # 设置过期时间为一天(单位为毫秒)
  subject: door     # 设置令牌的主题

总结

通过以上步骤,我们在Spring Boot应用中实现了基于JWT的登录认证功能。我们使用拦截器对用户请求进行拦截,只有拥有有效JWT的用户才能访问受保护的资源。这样可以有效地保证系统的安全性和用户体验。

相关推荐
AntBlack35 分钟前
计算机视觉 : 端午无事 ,图像处理入门案例一文速通
后端·python·计算机视觉
福大大架构师每日一题2 小时前
2025-06-02:最小可整除数位乘积Ⅱ。用go语言,给定一个表示正整数的字符串 num 和一个整数 t。 定义:如果一个整数的每一位都不是 0,则称该整数为
后端
Code_Artist2 小时前
[Mybatis] 因 0 != null and 0 != '' 酿成的事故,害得我又过点啦!
java·后端·mybatis
程序员博博2 小时前
看到这种代码,我直接气到想打人
后端
南雨北斗2 小时前
php 图片压缩函数
后端
L2ncE2 小时前
ES101系列08 | 数据建模和索引重建
java·后端·elasticsearch
还是鼠鼠3 小时前
Maven---配置本地仓库
java·开发语言·后端·maven
无问8173 小时前
SpringBoot:统一功能处理、拦截器、适配器模式
spring boot·后端·适配器模式
一只叫煤球的猫3 小时前
MySQL虚拟列:一个被低估的MySQL特性
数据库·后端·mysql
前端snow3 小时前
项目密码加密你是选择bcrypt还是crypto
前端·后端