Spring Boot实现JWT token自动续期的实现
作者:dreaming9420 发布时间:2022-02-12 03:48:40
标签:Spring,Boot,JWT,token,自动续期
1.为什么要 token自动续期
token中一般会包含用户的基本信息,为了保证token的安全性,一般会将token的过期时间设置的比较短,但是这样会导致用户因为token过期需要频繁登录,因此需要token自动续期。
2.如何实现token自动续期
登录时将token存入redis中,缓存有效期设置为 token有效时间的两倍(比token有效时间长即可)。
//创建token
String token = JwtUtil.createToken(sysUser.getId(), user.getUserName());
//将token放入redis中,key为用户的手机号+"token"
redisUtil.set(sysUser.getPhone() + GlobalConstant.TOKEN, token, JwtUtil.EXPIRE_TIME*2);
在 * 中重写public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)方法
/**
* token自动续期
*
* @param sysUser 用户实体
* @return 是否刷新成功
*/
private boolean refreshToken(SysUser sysUser) {
String token = request.getHeader(GlobalConstant.TOKEN);
String cacheToken = (String) (redisUtil.get(sysUser.getPhone() + GlobalConstant.TOKEN));
//请求头中不存在token,返回false
if (StringUtil.isEmpty(token)) {
logger.error("token不存在");
return false;
}
//用户是否登录只根据redis中token是否存在决定,redis中不存在token,返回false
if (StringUtil.isEmpty(cacheToken)) {
logger.error("用户未登录");
return false;
}
try {
//验证请求头中的token是否合法
JwtUtil.verify(token);
} catch (TokenExpiredException tokenExpiredException) {
/*若抛出token过期异常,检查redis中的是否存在token
如果存在,说明用户仍在操作,只是请求头中的token已经过期,此时需要对token进行续期*/
if (redisUtil.hasKey(sysUser.getPhone() + GlobalConstant.TOKEN)) {
//生成新的token,并以之前的key作为key放入redis中,以此重新刷新redis中的token的过期时间
String newToken = JwtUtil.createToken(sysUser.getId(), sysUser.getUserName());
redisUtil.set(sysUser.getPhone() + GlobalConstant.TOKEN, newToken, JwtUtil.EXPIRE_TIME * 2);
return true;
}
} catch (Exception e) {
//若抛出除token过期异常之外的其他异常,说明该token不合法
logger.error("token不合法");
return false;
}
return true;
}
JwtUtil工具类如下
import com.admin.common.constant.GlobalConstant;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
public class JwtUtil {
/**
* token私钥,不可以暴露
*/
public static final String TOKEN_SECRET_KEY = "tokenSecretKey";
/**
* token过期时间(秒)
*/
public static final int EXPIRE_TIME = 60;
/**
* 创建token
*
* @param userId 用户ID
* @param userName 用户名
* @return token
*/
public static String createToken(Long userId, String userName) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, EXPIRE_TIME);
return JWT.create()
//签发对象
.withAudience(userId + "")
//载荷
.withClaim("userName", userName)
//签发时间
.withIssuedAt(new Date())
//有效时间
.withExpiresAt(calendar.getTime())
//加密
.sign(Algorithm.HMAC256(TOKEN_SECRET_KEY));
}
/**
* 验证token合法性
*
* @param token token
* @return token是否合法
*/
public static void verify(String token) {
JWT.require(Algorithm.HMAC256(TOKEN_SECRET_KEY)).build().verify(token);
}
/**
* 通过token获取userId
*
* @return userId
*/
public static Long getUserIdByToken(HttpServletRequest request) {
String token = request.getHeader(GlobalConstant.TOKEN);
String userId = JWT.decode(token).getAudience().get(0);
return Long.valueOf(userId);
}
}
来源:https://blog.csdn.net/dreaming9420/article/details/121750732
0
投稿
猜你喜欢
- WPF换肤的设计原理,利用资源字典为每种皮肤资源添加不同的样式,在后台切换皮肤资源文件。截图上图中,第一张图采用规则样式,第二张图采用不规则
- RestTemplate 请求url中包含百分号 会被转义成25最初使用RestTemplate 进行远程调用方法如下:private St
- 一、# List泛型集合集合是OOP中的一个重要概念,C#中对集合的全面支持更是该语言的精华之一。为什么要用泛型集合?在C# 2.0之前,主
- Feign获取异常信息最近在使用Feign调用时,出现了异常,原本使用的是fallback,直接返回了自定义的结果@Override &nb
- 偶然机会看到一种对象初始的方式:// 新建一个列表,并赋值 "Harry","Tony","
- 一、MVC架构1、MVC是什么MVC是模型Model、视图View和控制器Controller的简称,是一种架构规范降低了业务逻辑与视图之间
- 近日,Eclipse经常挂掉,都是由于JVM崩溃的原因。每次都有以下错误日志:## A fatal error has been detec
- 本文是精讲RestTemplate第6篇,前篇的blog访问地址如下:RestTemplate在Spring或非Spring环境下使用精讲R
- IDEA安装后,前进 后退快捷按钮默认不在工具栏显示,需要手动将其添加到工具栏*按照图一选中Toolbar Run Actions ,点击右
- 内部类1. 内部类简介(1) 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。(2) 内部类成员可以
- 使用过Mybatis的同学,应该都知道,我们只需要编写mybatis对应的接口和mapper XML文件即可,并不需要手动编写mapper接
- Spring Data Elasticsearch提供了ElasticsearchTemplate工具类,实现了POJO与elasticse
- 本文实例讲述了java生成xml格式文件的方法。分享给大家供大家参考,具体如下:这里演示利用Java生成xml格式文件Demo中所用到的ja
- @RequestMapping注解注意点类上加没加@RequestMappin注解区别1.如果类上加了 @RequestMappin注解,那
- 本文实例讲述了C#多线程学习之使用定时器进行多线程的自动管理。分享给大家供大家参考。具体分析如下:Timer类:设置一个定时器,定时执行用户
- 引言ApplicationEvent以及Listener是Spring为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式,设
- 1. 测试文档、期望达到的目标文档效果用于测试的Word文档如下所示,包含的空白段落影响文章整体布局及美观性:目标文档效果:2. 辅助工具2
- 目录前言1、什么叫循环依赖呢2、具体出现循环依赖的代码逻辑3、解决循环依赖的代码实现总结前言本文基于springboot版本2.5.1 &n
- 查询文档 & 基本操作为了方便学习, 本节中所有示例沿用上节的索引按照ID单个GET class_1/_doc/1查询结果:{ &n
- java模拟实现图书检索系统 (基础版),供大家参考,具体内容如下练习实现3个简单的功能,没有优化,可以根据需求,自行添加想要实现的功能。B