原帖点我,一般的业务系统里 jwt token 都是如何刷新的?有没有最佳实践。
亮出一些观点
在 SpringBoot + redis + jwt token 的技术实践中,我的一点想法:
为的是服务器开销和业务需求之间寻求平衡。
网上搜到一些讨论(如下),欢迎大家畅所欲言
1
psnnf 2021-11-25 14:38:43 +08:00
如果要用 redis ,那么刷新 token 和不刷新 token 没有太大意义。
如果不用 redis ,那么就是前端 cookie 倒计时,计算 token 到期时间,快到期请求一下刷新 token 的 api |
![]() |
2
corningsun 2021-11-25 14:44:26 +08:00
后端提供 refresh_token 接口,返回新的 token ;
前端没有用户操作就不调用,过期就没了。 前端用户一直操作的情况下,在 token 有效期内刷新一次就好了。 |
3
gengchun 2021-11-25 14:46:07 +08:00
没有必要做成过期还要缓冲吧?
80 分钟无打操作重新登录,直接设置 X + 80 分钟的过期时间,超过 X 分钟就取一个新的 token 就好了。想减少拉 token 的次数,把 X 延长就好了。 |
![]() |
4
812603834 2021-11-25 14:48:07 +08:00 ![]() 每个公司的 token 机制都不一样,像我们公司要求
①必须设置过期时间,我们设置的 30 分钟 ②当操作频繁时,不能强行过期,就像用户在录入商品信息好不容易填写完了,提交..你给过期了,那会气死 所以保存 token 的同时,保存过期时间。每次请求验证 token 时,校验过期时间,如果剩余时间不足 10 分钟 那么就给 token 延长过期时间,延长 30 分钟,当期间不再有操作就自动过期。 |
![]() |
5
chendy 2021-11-25 14:52:29 +08:00
对于登录这种场景,按照一定业务规则生成 token 做 sesison id 就行了,用 JWT 发挥不出太大优势
然后就是 刷新、续订 这些标准操作了 |
![]() |
6
xuanbg 2021-11-25 14:54:39 +08:00 ![]() token 无状态,发出去就管不了。要管理 token ,就得有状态,还是 session id 一样的东西,何必要用 JWT 。自己把 session id 和防伪码 base64 编码一下做 token 不更简单?
|
![]() |
7
AllenHua OP @gengchun #3 这感觉和设置“缓冲时间”有些类似,假如 X == 40 ,那么每 40 分钟都会取一个新 token ,120 分钟未操作就让用户重新登录
@corningsun #2 嗯嗯 这还是什么时候前端去刷新的问题,后端肯定会提供 refresh_token 的接口 @psnnf #1 我看有些文章用了 redis 存储 token 但是没有用 redis 验证 token ,所以是存了个寂寞? |
![]() |
8
xuanbg 2021-11-25 14:56:46 +08:00
JWT 虽好,但适用的场景非常有限,不要滥用 JWT 。
|
9
psnnf 2021-11-25 15:05:15 +08:00
@AllenHua 绝大多数公司用 JWT 后,然后有一些需求做不到,只能用到 redis 了,比如用户强行下线,一个用户只能一台设备登录到系统。。。等待这些需求,JWT 做不了
|
![]() |
10
AllenHua OP @psnnf #9 是的。比如用户强行下线,redis delete key 然后 jwt 已签发的 token 无法撤回但是由于拦截器拦截请求校验的是 jwt verify 和 redis hasKey ,两者均返回 true 才可以访问资源,所以这样 redis 也能充分利用到了
@812603834 #4 token 默认的载荷 payload 中就有 exp 字段吧,是个时间戳,我现在是声明了一个东八区给前端,这样在时间上前后端就没有误会 > 如果剩余时间不足 10 分钟 那么就给 token 延长过期时间,延长 30 分钟,当期间不再有操作就自动过期。 是这样的。感谢分享 @812603834 |
![]() |
11
swulling 2021-11-25 15:10:51 +08:00
我的结论就是别用 JWT ,用中心化 Session ,比如 Redis ~
|
12
gengchun 2021-11-25 15:11:17 +08:00
@AllenHua 这样就是少了一个变量,少一次判断。另外第三方库可以直接实现。
个人觉得,放了 redis 其实是为了实现流控,计费,或者蜜罐这些功能的话。 而且一旦有 redis 的话,可以通过 redis 来实现对用户的管控。那样在不考虑合规因素的影响下,也没有必要把 jwt 的过期时间设置的太短,一般以天或者周过期 token 就足够了。 |
13
mxT52CRuqR6o5 2021-11-25 15:16:24 +08:00
通过存储到数据库给 jwt 添加 session 的特性,不就是另外又发明了一套 session 吗
|
![]() |
14
chendy 2021-11-25 15:16:46 +08:00
@xuanbg +1
JWT 其实更适合服务之间用,网关鉴权后生成然后给后续服务传递着用,服务可以拿到可信的用户身份不需要再请求用户服务,请求处理结束就扔掉不用担心踢人之类的事情 |
![]() |
15
aboat365 2021-11-25 15:21:38 +08:00
|
![]() |
16
IvanLi127 2021-11-25 15:29:09 +08:00
我觉得加 refresh_token ,这个 token 就是普通的 sessionID ,或者是一个 jwt , 但用户信息从数据库里取。前端定时更新 access_token 就好了。
|
![]() |
17
zzl22100048 2021-11-25 15:30:25 +08:00
OIDC 不好用么
|
18
joesonw 2021-11-25 16:52:09 +08:00
上 redis 还要 jwt 干嘛? 只是 session 是正查, jwt revocation 是反查. 每次请求最终还是要去到 redis 查.
|
![]() |
19
AllenHua OP @swulling #11 我了解一下
@gengchun #12 网页应用我看 qq 邮箱之类的都是一两个小时没有操作会让用户重新登录的吧,我是觉得一周时间太长(说到底还是要看具体业务) @aboat365 #15 谢谢分享🙏🏻 @zzl22100048 #17 我了解一下 @joesonw #18 🤨 |
20
zhleonix 2021-11-25 21:02:17 +08:00 ![]() JWT 可以有 JTI 唯一 ID ,需要支持注销的话广播一下 JTI 到各个访问控制点作为黑名单就行了。平时不用每次访问都去 redis 或者数据库验证,使用 JWT 自带的签名校验。
|
21
hhyyd 2021-11-25 23:04:14 +08:00 ![]() 我做了两个项目的登录功能后,目前的方案是:accessToken 过期时间设置短些,如果过期则前端用 refreshToken 获取新 token 即可(对用户来说是无感知的替换了 accessToken )。jwt 和 redis 选择一种方案即可,jwt 本身有附带信息解密即可,如果用 redis 关联 token-用户信息查询也很快。
两种方案都有尝试过,相对更倾向加上 redis 去做记录,如果想要在服务端清除用户本次的登录状态,如果有 redis 记录就方便些;如果用的是纯 jwt 的话,不是很好办,最终还是要服务端记录这个 jwt 。 楼主的过期超时 20 分钟的缓冲,其实就是 refreshToken 方式, 刚开始接触的时候,也用过这种 token 替换 token 的方式,后来发现还有 refreshToken 这种方式,非常适合这种频繁操作时延长 token 有效期的场景 |
23
NXzCH8fP20468ML5 2021-11-26 00:30:01 +08:00 via Android ![]() 每次请求都用中间件判断 jwt ,快过期了就发一个新的,附加到 header 上。拦截器发现新 token 的就替换旧的。
|
![]() |
24
nl101531 2021-11-26 09:36:55 +08:00 via iPhone
设定过期时间,服务端检测每次请求时,token 还有多久过期,在一定允许时间范围内,重新下发。 这个方案需要 cookie 承接 token
|
25
gengchun 2021-11-26 14:33:47 +08:00
@hhyyd refesh token 总感觉有些多余。一次要整两个 token ,一个 refresh 和一个 access 。
而目的好像只是防止第三方的 js 脚本可以读取 access token ,但是读不了 refresh token 。这个设计还有别的目的吗? |
27
chtcrack 2021-11-27 16:35:19 +08:00
从来不用 jwt,都是自己设计一套 token 系统..
|
![]() |
28
kssss 2021-11-28 09:26:45 +08:00
刷新啥,让用户退出重新登录
|