本文基于上一篇文章:《Spring Security(三)整合 JWT 实现无状态登录示例》。
在 SpringSecurity
整合 JWT
实现无状态登录示例中,我们在 JwtAuthenticationFilter
(自定义JWT
认证过滤器) 解析 Token
成功后,提供了续签逻辑:
1 | /** |
这里的逻辑是:Token
未过期并且当前时间已经超过 Token
有效时间的一半,重新生成一个 refreshToken
,并返回给前端,前端需要用 refreshToken
替换之前旧的 Token
。
Token续签优化方案
预期效果:前端不需要手动替换 Token
,每次用 Token
请求资源时自动续期。
实现方案:引入 Redis
,实现逻辑:
- 登录成功后将
Token
存储到Redis
里面(k,v都为Token
的值),并设置Redis
过期时间为:Token
过期时间。 - 用户发起请求时,每次都根据k为
Token
的键去换取Redis
的值,这里命名为cacheToken
:- 当
cacheToken
在有效期内,重设Redis
过期时间为:当前时间 + (cacheToken
过期时间 -cacheToken
签发时间)。 - 当
cacheToken
已过期(Redis
在有效期内),则JWT
重新生成Token
并覆盖v值(这时候k、v值不一样了),然后设置Redis
过期时间为:cacheToken
过期时间。 - 若
Redis
也过期,取不到cacheToken
,则拒绝访问或返回错误信息,需要重新登录。
- 当
具体实现
1. 在 pom.xml
中引入 Redis
依赖:
1 | <dependency> |
2. 在 application.yml
配置文件中配置 Redis
:
1 | spring: |
3. 简单的 RedisService
封装
1 |
|
4. 修改JWT登录过滤器 JwtLoginFilter
,构造方法中加入 RedisService
,并生成 Token
后存入 Redis
:
1 |
|
5. 修改JWT认证过滤器 JwtAuthenticationFilter
,构造方法中加入 RedisService
,并添加 Token
续签逻辑:
1 |
|
6. 修改 SpringSecurity
配置类,注入 RedisService
:
1 |
|
源码地址:https://github.com/chaooo/spring-security-jwt.git,
这里我将本文的基于Redis的Token自动续签优化放在github源码tag的V2.0中,防止后续修改后代码对不上。