You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么需在服务端数据库存储JWT的refresh token?存储access token是否更好?

JWT会话方案相关问题解答

为什么需要存储refresh token

即使refresh token是服务端签名、不可篡改、可自主校验过期,存储的核心作用是实现主动令牌作废能力,解决两个核心问题:

  • 令牌泄露后可以立即作废被盗的refresh token,避免攻击者在令牌有效期内持续申请新的access token窃取用户信息
  • 支持多端登录管理,用户可以单独登出某一台设备的会话,不会影响其他设备的正常登录
    如果不存储refresh token,服务端只能被动接受所有签名有效、未过期的refresh token,完全没有主动管控会话的能力。

能否只存储user_id替代存储refresh token

不能,会出现两个明显缺陷:

  • 无法区分同个用户的多端会话,只要是该用户的有效refresh token都会被认可,用户登出时只能作废该用户所有会话,无法单独指定某一端登出,体验极差
  • 无法限制refresh token的使用次数,正常方案中refresh token可以设计为单次使用(每次刷新就生成新的refresh token同时作废旧的),如果只存user_id完全做不到这个逻辑,泄露的refresh token可以一直用到过期。

存储最新access token的方案是否有优势

该方案的唯一收益是可以解决你提到的「旧access token未过期时登出仍可使用」的问题,但弊远大于利:

  • 完全丧失JWT的无状态优势,每次业务接口请求都需要查询Redis校验access token是否为最新值,Redis的查询压力会比存储refresh token的方案大几十上百倍:毕竟refresh token只有在access token过期时才会调用,频率远低于普通业务接口
  • 你预设的「只会在前一个access token过期后才生成新的access token」逻辑在实际场景中很难落地:客户端时间误差、网络波动、用户切网等场景都可能触发提前刷新请求,如果严格限制只有过期才能刷新,会频繁出现用户正常使用时被迫重新登录的问题
  • 该方案本质已经退化为类Session的实现,和直接用Session ID存用户状态没有本质区别,完全没必要额外引入JWT的复杂度

针对你的应用场景的优化建议

  • 优先级最高的操作是开通HTTPS,你当前未使用HTTPS的情况下,所有httpOnly cookie、令牌签名的防护都完全无效,中间人可以直接抓包获取所有令牌,没有任何会话安全可言
  • 如果要降低Redis存储成本,可以只存refresh token的哈希值而非明文,验证时将客户端提交的refresh token做哈希后对比即可,安全性更高
  • 可以给每个refresh token增加唯一标识jti字段,Redis中以user_id:jti为键存储对应令牌的过期时间,登出时只需要删除对应jti的键即可实现单端登出,灵活性更高

内容的提问来源于stack exchange,提问作者Karthik Prakash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 20:06:03