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);
}

JWT token验证后,通过 ThreadLocal 进行传值的更多相关文章

  1. 微信订阅号开发之token验证后,自动回复消息功能做好,发送消息没有返回

    相信很多人会跟我一样,token验证之后,发送消息给订阅号,没有消息返回. 以下,说一下我辛苦调试得到的解决办法: 首先,token验证: 自己写的token一直验证失败,找了好久,没有发现bug.实 ...

  2. koa2+redis+jwt token验证,简单注册登录

    首先新建文件夹命名koa-server,npm init,相关包的安装就不说了,这是我的package.json 新建index.js文件,编码如下,config全局配置不用管,redis是一个简单的 ...

  3. jwt Token验证与解析

    网上似乎没有相关代码 贴上一段Token的解析认证 [TestMethod] public void TestMethod1() { string Token = "eyJhbGciOiJI ...

  4. 【JWT】JWT+HA256加密 Token验证

    目录 Token验证 传统的Token验证 JWT+HA256验证 回到顶部 Token验证 最近了解下基于 Token 的身份验证,跟大伙分享下.很多大型网站也都在用,比如 Facebook,Twi ...

  5. Spring Cloud OAuth2.0 微服务中配置 Jwt Token 签名/验证

    关于 Jwt Token 的签名与安全性前面已经做了几篇介绍,在 IdentityServer4 中定义了 Jwt Token 与 Reference Token 两种验证方式(https://www ...

  6. 基于jwt的token验证

    一.什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519). 该token被设计为紧凑且安全的,特别适用于分布 ...

  7. webapi中使用token验证(JWT验证)

    本文介绍如何在webapi中使用JWT验证 准备 安装JWT安装包 System.IdentityModel.Tokens.Jwt 你的前端api登录请求的方法,参考 axios.get(" ...

  8. Asp.Net Core 3.1 学习3、Web Api 中基于JWT的token验证及Swagger使用

    1.初始JWT 1.1.JWT原理 JWT(JSON Web Token)是目前最流行的跨域身份验证解决方案,他的优势就在于服务器不用存token便于分布式开发,给APP提供数据用于前后端分离的项目. ...

  9. 【Azure Developer】如何验证 Azure AD的JWT Token (JSON Web 令牌)?

    问题描述 使用微软Azure AD,对授权进行管理.通过所注册应用的OAuth API(https://login.chinacloudapi.cn/{TENANT ID}/oauth2/v2.0/t ...

  10. Django restframework之Token验证的缺陷及jwt的简单使用

    一.主要缺陷: 1.Token验证是放在一张表中,即authtoken_token中,key没有失效时间,永久有效,一旦泄露,后果不可想象,安全性极差. 2.不利于分布式部署或多个系统使用一套验证,a ...

随机推荐

  1. 文心一言 VS 讯飞星火 VS chatgpt (133)-- 算法导论11.2 5题

    五.用go语言,假设将一个具有n个关键字的集合存储到一个大小为 m 的散列表中.试说明如果这些关键字均源于全域U,且|U|>nm,则U 中还有一个大小为n 的子集,其由散列到同一槽位中的所有关键 ...

  2. TypeScript学习小结:基础使用

    TypeScript学习小结:基础使用 某册子买了两年多了,到最近才开始学习TypeScript,拖延症的严重症状了:不过我还是深信人做一件事是需要一个契机的. 学完之后整体感受是:TypeScrip ...

  3. AcWing 456. 车站分级

    原题链接AcWing 456. 车站分级 抽象出题意,停靠过的车站的等级一定严格大于为停靠过的车站的等级,且不存在环,例如车站\(A\)等级大于车站\(B\),则\(A >= B + 1\),不 ...

  4. MIGO配置过账后自动打印

    1.业务需求 本文档介绍,当MIGO发货过账时,自动打印自开发表格. 2.打印程序 复制标准配置中调用的程序和子例程,到新的程序(路径可参考下文系统配置) 只用复制子例程entry_wa01即可,参考 ...

  5. Python 中的单下划线和双下划线

    哈喽大家好,我是咸鱼 当我们在学习 Python 的时候,可能会经常遇到单下划线 _ 和双下划线 __ 这两种命名方式 单下划线 _ 和双下划线 __ 不仅仅是只是一种简单的命名习惯,它们在 Pyth ...

  6. 【外包杯】【报错】微信小程序 “[app.json 文件内容错误]app.json:未找到[“pages”][0]对应 pages/xx/xx.wxml(或其他)文件” 报错 的简单解决方案(已解决)

    问题的解决方案 删除components目录下的uni-link文件夹

  7. Opencv实例练习

    实例所用的函数可在另一篇文章查询:  https://www.cnblogs.com/Zhouce/p/17867164.html 1.图像读取 1 import cv2 # 引入opencv库 2 ...

  8. Cannot resolve symbol ‘c:forEach‘;Cannot resolve taglib with uri http://java.sun.com/jsp/jstl/corede

    #### Cannot resolve taglib with uri http://java.sun.com/jsp/jstl/core:等类似,都是因为 在jsp页面中加入<%@ tagli ...

  9. AtCoder_abc327

    T1 ab 循环从s[0] 到s[n-2] 判断有无ab相邻 T2 A^A 两层循环枚举就可以了 由于aa会增长的很快,所以当a=16时aa就已经大于\(10^{18}\)了,一定不会T 就这么点数打 ...

  10. IDEA配置自定义标签,实现高亮注释~

    为什么要写这么一篇博客呢? 不知道大家有没有这样的一种苦恼,就是在写代码的时候遇到复杂的核心的代码,想加一个特殊的注释方便后期自己或者同事查看,但是这玩意IDEA好像只给我们提供了两个 FIXME : ...