JWT token 过期续签的问题想法
JWT token 过期续签的问题想法
-
服务端保存签发的token,进行失效判断,使用Redis保存
-
如果服务端,不保存token
-
客户端解析 token中 payload的数据,添加失效时间,再失效时间之前再次进行签到
-
客户端 保存两个 token:access_token、refresh_token
refresh_token 的有效期比 access_token 长,成倍数2倍,当access_token 失效后,使用refresh_token去重新进行续签
如果refresh_token也失效,需要重新登录
当refresh_token有效的时候,进行续签的时候,需要对已经失效的access_token进行校验,校验access_token过期时间必须最近的,不能太远
access_token中的payload存储用户相关的申明信息
refresh_token中的payload中只保存过期时间,或者与access_token有关的一些的信息
refresh_token是对access_token服务的,不能去替代,不然就失去了原本的意义了
那么一般的设计就很清楚了 token(jwt) + refresh_token , 因为token(jwt)自己内含全部的验证数据,如果丢失就麻烦大了,所以有效期一定要尽可能短一些,比如5分钟。过期后,就用refresh_token 去刷新一下,获取新的token。 (refresh_token 因为是偶尔使用一次,用在MYSQL里查库或者redis,都比较稳当了)
---------------------------
补充:为什么要refresh_token去刷新,是因为token频繁传输,容易被窃取,refresh_toke则只有刷新token的时候使用一次,用完一次就报废了
存在的问题:token不能作废,只能过期,保存在服务端的时候,可以定期的去清理token,不在服务端的token都可以不认
-
个人觉得的使用范围
- 临时令牌(只签发不续签)
- 永久令牌(长期有效,丢失只能屏蔽掉加密的秘钥)
接口资源保护,只有有令牌才能访问
场景举例:类似于 gihtub或者码云,使用令牌向存储库中推送文件
网上有人提出了一种思路,
在不用缓存的情况下,可以将 每个用户的信息和加密令牌使用的秘钥secret绑定起来,
中间甚至可以加入用户权限相关信息,具体根据业务决定
那么在注销或者修改密码的时候去更新绑定的秘钥,同时可以再加上更新的时间
用户id | 登录秘钥 | 临时秘钥 | 长期秘钥
登录秘钥:会话期间使用,注销或者修改密码修改
临时秘钥: 适用颁布临时令牌,修改密码时重置
长期令牌:适用颁布长期立牌,修改密码时重置
存在问题,每次都需要去根据用户id,查数据库,效率不行,都已经查数据了,不如直接用数据库的秘钥作为临牌
个人想法,可不可以使用
用户信息中的某个数据 与 一个秘钥 进行某些运算 可以得到 登录秘钥
signature 中需要分成两部分,JWT签名 + 用户个人私钥,将此部分再使用可逆向解密的算法再次进行加密,作为新的签名
校验部分
对前端传来的 新的签名先进行解密,拿到用户个人私钥与程序的公钥进行运算,得出jwt加密的秘钥,再去进行校验 jwt签名是否有效
用户续签的时候去查数据中用户的登录秘钥,个人私钥+程序公钥 = 用户的登录秘钥,每次用户注销改密的时候,修改掉登录秘钥,更新数据库
其他
SS0单点登录
- 多了一个授权中心,中心颁发令牌和存储颁发了的令牌
- 子系统只认中心颁发的令牌,需要向中心核实令牌真实性
不考虑令牌丢失情况下,可以使用直接续签的策略
前端定时刷新令牌,后端重新生成令牌给前端
再安全一点,使用双token