Spring通过token获取登录用户信息的方式及优化

发布于:2024-04-29 ⋅ 阅读:(25) ⋅ 点赞:(0)

问题:当请求的header里携带token时,如何直接通过token获取到当前登录用户的信息

1. 通过拦截器和ThreadLocal

  1. Interceptor
@Component
public class WmTokenInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        if (StringUtils.isNotBlank(token)){
            Claims claims = AppJwtUtil.getClaimsBody(token);
            WmUser wmUser = new WmUser();
            wmUser.setId((int)claims.get("id"));
            WmThreadLocalUtil.set(wmUser);
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        WmThreadLocalUtil.remove();
    }
}
  1. WebMvcConfig
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Resource
    WmTokenInterceptor wmTokenInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(wmTokenInterceptor).addPathPatterns("/**").excludePathPatterns("/wemedia/login/in");
    }
}
  1. ThreadLocalUtil
public class WmThreadLocalUtil {
    private static ThreadLocal<WmUser> WM_USER_THREAD_LOCAL = new ThreadLocal<>();

    public static WmUser get(){
        return WM_USER_THREAD_LOCAL.get();
    }
    
    public static void set(WmUser wmUser){
        WM_USER_THREAD_LOCAL.set(wmUser);
    }

    public static void remove(){
        WM_USER_THREAD_LOCAL.remove();
    }
}
  1. Service中获取用户信息示例
WmUser wmUser = WmThreadLocalUtil.get();

2. 直接在服务层获取HttpServletRequest

  1. 工具类
public class RequestContextUtil {

    /****
     * 获取请求头   token  HttpServletRequest
     */
    public static String getHeader(String key){
        //RequestContextHolder 获取当前请求的请求封装对象和响应封装对象
        //1)获取HttpServletRequest
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        //2)通过HttpServletRequest获取指定请求头
        return request.getHeader(key);
    }

    /***
     * 获取token
     */
    public static Map<String,Object> token(){
        String token = getHeader("token");
        return AppJwtUtil.getClaimsBody(token);
    }

    /***
     * 获取token指定的key
     */
    public static <T>T get(String key){
        Map<String, Object> token = token();
        return (T) token.get(key);
    }
}
  1. Service中获取用户信息示例
int id = RequestContextUtil.get("id");