springboot token jwt

一、导入依赖

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <scope>runtime</scope>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <scope>runtime</scope>
    <version>0.11.2</version>
</dependency>

二、ThreadLocal工具类

1、LoginUser

package com.wt.lease.common.login;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class LoginUser {
    private Long userId;
}

2、LoginUserHolder

package com.wt.lease.common.login;

public class LoginUserHolder {
    public static ThreadLocal<LoginUser> threadLocal = new ThreadLocal<>();
    public static void setLoginUser(LoginUser loginUser) {
        threadLocal.set(loginUser);
    }

    public static LoginUser getLoginUser() {
        return threadLocal.get();
    }

    public static void clear() {
        threadLocal.remove();
    }
}

三、JwtUtils工具了类

1、yaml文件,配置参数

#jwt配置
jwt:
  token:
    tokenExpiration: 120 #有效时间,单位小时
    tokenSignKey: M0PKKI6pYGVWWfDZw90a0lTpGYX1d4AQ  #当前程序签名秘钥 自定义

2、JwtUtil

package com.wt.lease.common.utils;

import com.wt.lease.common.exception.LeaseException;
import com.wt.lease.common.result.ResultCodeEnum;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.Date;

@Data
@Component
@ConfigurationProperties(prefix = "jwt.token")
public class JwtUtil {
    private  long tokenExpiration; //有效时间,单位小时
    private  String tokenSignKey;  //当前程序签名秘钥


    // 生成token
    public String createToken(Long userId){
        System.out.println("1. userId = " + userId);
        SecretKey secretKey = Keys.hmacShaKeyFor(tokenSignKey.getBytes());
        return Jwts.builder()
                .setSubject("USER-INFO")
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration * 1000 * 60 * 60))
                .claim("userId", userId)
                .signWith(secretKey)
                .compact();
    }

    // 解析token 配合 自定义的 异常和返回码
    public Claims parseToken(String token){
        SecretKey secretKey = Keys.hmacShaKeyFor(tokenSignKey.getBytes());
        if (token==null){
            // 无token,未登录
            throw new LeaseException(ResultCodeEnum.APP_LOGIN_AUTH);
        }
        try {
            // 正常
            JwtParser jwtParser = Jwts.parserBuilder().setSigningKey(secretKey).build();
            return jwtParser.parseClaimsJws(token).getBody();
        }catch (ExpiredJwtException e){
            // 过期
            throw new LeaseException(ResultCodeEnum.TOKEN_EXPIRED);
        }catch (JwtException e){
            throw new LeaseException(ResultCodeEnum.TOKEN_INVALID);
        }
    }
}

四、拦截器

package com.wt.lease.web.admin.custom.interceptor;

import com.wt.lease.common.login.LoginUser;
import com.wt.lease.common.login.LoginUserHolder;
import com.wt.lease.common.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

@Component
public class AuthenticationInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        Claims claims = jwtUtil.parseToken(token);
        Long userId = claims.get("userId", Long.class);
        LoginUserHolder.setLoginUser(new LoginUser(userId));
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        // 清除 threadlocal
        LoginUserHolder.clear();;
    }
}

五、注册

package com.wt.lease.web.admin.custom.config;

import com.wt.lease.web.admin.custom.converter.StringToBaseEnumConverterFactory;
import com.wt.lease.web.admin.custom.interceptor.AuthenticationInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    private StringToBaseEnumConverterFactory stringToBaseEnumConverterFactory;
    @Autowired
    private AuthenticationInterceptor authenticationInterceptor;
    @Override
    public void addFormatters(FormatterRegistry registry) {
        WebMvcConfigurer.super.addFormatters(registry);
        registry.addConverterFactory(this.stringToBaseEnumConverterFactory);
    }
    
    // 拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(this.authenticationInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin/login/**");
    }
}

六、使用

1、获取token

String token = jwtUtil.createToken(userId字段);

2、通过threadLocal获取 创建传入 的userId

Long userId = LoginUserHolder.getLoginUser().getUserId();

 

编写ThreadLocal工具类
posted @ 2025-05-16 00:07  市丸银  阅读(70)  评论(0)    收藏  举报