jwt的token令牌实现登录校验功能

200 阅读3分钟

token令牌分为三部分:Header(头部):放着签名算法和令牌类型(token就是一种令牌类型),payload(负载):可以放着一些自定义字段,存储的时候会被Base64编码,Signature(签名):对Header和Payload进行编码的结果,通过指定的签名算法和密钥来进行计算。这三部分由.分割。

步骤1:引入jwt相关依赖

<!--jwt依赖-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>${jwt}</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>${jwt}</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>${jwt}</version>
    <scope>runtime</scope>
</dependency>

步骤2:创建Jwt工具类

jwt工具类用于生成jwt的token令牌,解析token令牌,还有判断令牌是否有效。

定义密钥和过期时间

    private static final String SECRET="SECRET="eyJ1c2VybmFtZSI6ImRqIiwicGFzc3dvcmQiOjEyMzQ1Nn0=";//定义密钥";
    private static final Long  EXPIRATION = 3600L; //定义过期时间

密钥可以去浏览器的base64编码生成器来获得。通过自己指定的数据来进行编码。

生成token令牌的方法

//生成令牌
    public static String generateToken(Map<String, String> claims) {
        return Jwts.builder()
                .setClaims(claims)//传入自定义数据
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000))//生成过期时间
                .signWith(SignatureAlgorithm.HS256, SECRET)//签名算法和密钥
                .compact();
    }

setClaims用来组成token令牌的Payload,比如接收到前端传过来的用户名和id,可以封装成一个Map集合作为参数传进去,setExpiration用来指定过期时间,多久会失效,这里是当前时间加上刚刚定义的时间,signWith传递的是签名算法和密钥。

解析token令牌的方法

public static Claims parseToken(String token) {
    return Jwts.parser()
            .setSigningKey(SECRET)
            .parseClaimsJws(token)
            .getBody();
}

setSigningKey传入生成token令牌的密钥,parseClaimsJws传入获得到的token令牌。这个方法主要用于校验token是否有效,比如结合下面的方法。

校验token令牌

public static boolean validateToken(String token) {
    try {
        parseToken(token);
        return true;
    } catch (Exception e) {
        return false;
    }

如果报错了,说明令牌有问题,比如过期之类的,执行一些逻辑,比如跳转到登录界面,如果没报错,就证明令牌有效。

步骤3:创建一个拦截器

创建一个类实现HandlerInterceptor接口,实现里面的perHandle方法。

@Slf4j
@Component
public class JwtTokenInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            //当前拦截到的不是动态方法,直接放行
            return true;
        }

        // 1. 从请求头获取Token
        String token = request.getHeader("token");
        if (token == null || !token.startsWith("Bearer ")) {
            log.info("token为空:{}",token);
            response.setStatus(401);
            return false;
        }
        token = token.substring(7);
        boolean flag = JwtUtil.validateToken(token);
        if (flag) {
            return true;
        }
        log.info("token无效:{}",token);
        response.setStatus(401);
        return false;
    }

主要就是拦截后的逻辑,先从请求头拿到浏览器被前端拿到的token,如果无效就返回401状态码,并且返回一个false。boolean类型的返回值用于告诉拦截器,什么时候放行,什么时候不放。

步骤四:注册拦截器

创建了一个拦截器后,肯定是要去配置,启动的,这里创建了一个配置类,并且实现了WebMvcConfigurer接口 重写了addInterceptors这个方法。

@Configuration
@Slf4j
public class WebMvcConfiguration implements WebMvcConfigurer {
    @Autowired
    private JwtTokenInterceptor jwtTokenInterceptor;
    /*@Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtTokenInterceptor)
                .addPathPatterns("/*")   // 拦截路径
                .excludePathPatterns("/admin/login"); // 排除路径
    }*/

将刚刚编写的拦截器依赖注入,然后在方法里面开始注册,这里注册的时候指定了拦截的路径,排除拦截的路径,比如登陆时的路径。

以上是我对token令牌登录校验功能的一个理解,希望这篇博客可以对你有帮助。有不足的地方页欢迎一起到评论区进行交流讨论