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

简介: 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);
    }

 

目录
相关文章
|
6月前
|
存储 前端开发 JavaScript
Cookie、Session、Token、JWT 是什么?万字图解带你一次搞懂!看完这篇,你连老奶奶都能教
HTTP 协议是无状态的,就像一个“健忘”的银行柜员,每次请求都像第一次见面。为解决这一问题,常用的技术包括 Cookie、Session 和 Token。Cookie 是浏览器存储的小数据,Session 将数据存在服务器,Token(如 JWT)则是自包含的无状态令牌,适合分布式和移动端。三者各有优劣,适用于不同场景。
619 0
Cookie、Session、Token、JWT 是什么?万字图解带你一次搞懂!看完这篇,你连老奶奶都能教
|
JSON 安全 Go
Go语言中使用JWT鉴权、Token刷新完整示例,拿去直接用!
本文介绍了如何在 Go 语言中使用 Gin 框架实现 JWT 用户认证和安全保护。JWT(JSON Web Token)是一种轻量、高效的认证与授权解决方案,特别适合微服务架构。文章详细讲解了 JWT 的基本概念、结构以及如何在 Gin 中生成、解析和刷新 JWT。通过示例代码,展示了如何在实际项目中应用 JWT,确保用户身份验证和数据安全。完整代码可在 GitHub 仓库中查看。
2423 1
|
存储 中间件 API
ThinkPHP 集成 jwt 技术 token 验证
本文介绍了在ThinkPHP框架中集成JWT技术进行token验证的流程,包括安装JWT扩展、创建Token服务类、编写中间件进行Token校验、配置路由中间件以及测试Token验证的步骤和代码示例。
ThinkPHP 集成 jwt 技术 token 验证
|
JSON 安全 数据安全/隐私保护
从0到1搭建权限管理系统系列三 .net8 JWT创建Token并使用
【9月更文挑战第22天】在.NET 8中,从零开始搭建权限管理系统并使用JWT(JSON Web Tokens)创建Token是关键步骤。JWT是一种开放标准(RFC 7519),用于安全传输信息,由头部、载荷和签名三部分组成。首先需安装`Microsoft.AspNetCore.Authentication.JwtBearer`包,并在`Program.cs`中配置JWT服务。接着,创建一个静态方法`GenerateToken`生成包含用户名和角色的Token。最后,在控制器中使用`[Authorize]`属性验证和解析Token,从而实现身份验证和授权功能。
1314 4
【Azure APIM】在APIM中实现JWT验证不通过时跳转到Azure登录页面
【Azure APIM】在APIM中实现JWT验证不通过时跳转到Azure登录页面
115 2
【Azure Developer】记录一段验证AAD JWT Token时需要设置代理获取openid-configuration内容
【Azure Developer】记录一段验证AAD JWT Token时需要设置代理获取openid-configuration内容
166 0
|
JSON Java API
【Azure Developer】如何验证 Azure AD的JWT Token (JSON Web 令牌)?
【Azure Developer】如何验证 Azure AD的JWT Token (JSON Web 令牌)?
493 0
|
JSON 算法 API
【Azure API 管理】APIM 配置Validate-JWT策略,验证RS256非对称(公钥/私钥)加密的Token
【Azure API 管理】APIM 配置Validate-JWT策略,验证RS256非对称(公钥/私钥)加密的Token
301 0
|
JSON 安全 Java
什么是JWT?如何使用Spring Boot Security实现它?
什么是JWT?如何使用Spring Boot Security实现它?
2234 5