JWT token验证后,通过 ThreadLocal 进行传值

Spring Boot JWT 用户认证

JWT token验证后,通过 ThreadLocal 进行传值,在服务层直接使用 Threadlocal 获取当前用户,的Id、姓名,进行行为记录

定义一个用户实体类

package com.vipsoft.core.user.entity;

import com.fasterxml.jackson.annotation.JsonFormat;

import java.io.Serializable;
import java.util.Date;

public class TokenEntity implements Serializable {

    private String userId;

    private String userName;

    private String accessToken;

    private String refreshToken;

    private int expiry;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.sssZ", timezone = "GMT+8")
    private Date expiryDate;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.sssZ", timezone = "GMT+8")
    private Date createTime;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    public String getRefreshToken() {
        return refreshToken;
    }

    public void setRefreshToken(String refreshToken) {
        this.refreshToken = refreshToken;
    }

    public int getExpiry() {
        return expiry;
    }

    public void setExpiry(int expiry) {
        this.expiry = expiry;
    }

    public Date getExpiryDate() {
        return expiryDate;
    }

    public void setExpiryDate(Date expiryDate) {
        this.expiryDate = expiryDate;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}

SessionBase

package com.vipsoft.core.user.entity;

public class SessionBase {

    /**
     * 用来存放登录用户的信息
     */
    public static final ThreadLocal<TokenEntity> CURRENT_MEMBER = new ThreadLocal();

}

AuthorizationInterceptor

package com.vipsoft.web.boot.interceptor;


import cn.hutool.core.util.StrUtil;
import com.vipsoft.core.user.entity.SessionBase;
import com.vipsoft.core.user.entity.TokenEntity;
import com.vipsoft.web.boot.annotation.JwtIgnore;
import com.vipsoft.web.boot.exception.CustomException;
import com.vipsoft.web.boot.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

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


@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private JwtUtils jwtUtils;


    public static final String USER_KEY = "userId";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//
        // 忽略带JwtIgnore注解的请求, 不做后续token认证校验
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            JwtIgnore jwtIgnore = handlerMethod.getMethodAnnotation(JwtIgnore.class);
            if (jwtIgnore != null) {
                return true;
            }
        }

        if (HttpMethod.OPTIONS.equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }

        //获取用户凭证
        String token = request.getHeader(jwtUtils.getHeader());
        if (StrUtil.isBlank(token)) {
            token = request.getParameter(jwtUtils.getHeader());
        }

        //凭证为空
        if (StrUtil.isBlank(token)) {
            throw new CustomException(HttpStatus.UNAUTHORIZED.value(), "token 不能为空");
        }

        Claims claims = jwtUtils.getClaimByToken(token);
        if (claims == null || jwtUtils.isTokenExpired(claims.getExpiration())) {
            throw new CustomException(HttpStatus.UNAUTHORIZED.value(), "token  失效,请重新登录");
        }


        String[] userinfo = claims.getSubject().split("\\|");
        //判断redis是否存在这个key
//        String redisKey = StrUtil.indexedFormat("TOKEN_USER", userinfo[0]);
//        String redisValue = redisTemplate.opsForValue().get(redisKey);
//        if (!token.equals(redisValue)) {
//            throw new CustomException(HttpStatus.UNAUTHORIZED.value(), "token 失效,请重新登录");
//        }

        //新增ThreadLocal返回用户信息的方式
        TokenEntity tokenEntity = new TokenEntity();
        tokenEntity.setUserId(userinfo[0]);
        tokenEntity.setUserName(userinfo[1]);
        tokenEntity.setAccessToken(token);
        SessionBase.CURRENT_MEMBER.set(tokenEntity);

        //也可以通过 Request 数据传送,设置userId到request里,后续根据userId,获取用户信息
        request.setAttribute(USER_KEY, userinfo[0]);
        return true;
    }
}

调用

@Override
public void insert(Users user) {
        TokenEntity tokenEntity = SessionBase.CURRENT_MEMBER.get();
        String userId = tokenEntity != null ? tokenEntity.getUserId() : "";
        String userName = tokenEntity != null ? tokenEntity.getUserName() : "";
        user.setCreateUserId(userId);
        user.setCreateUserName(userName);
        userMapper.insert(user);
    }

 

posted @ 2022-09-13 21:27  VipSoft  阅读(322)  评论(0编辑  收藏  举报