如何在登出场景下处理JWT refresh_token?含多场景技术疑问
JWT Refresh Token 场景问题解答
问题1:新旧Refresh Token能否共存?
可以共存,但需要结合业务需求做合理限制:
- 如果支持多设备登录,允许同一用户持有多个有效RT是合理的,比如用户同时在手机、电脑登录
- 建议设置用户可持有RT的最大数量,超过上限时自动淘汰最早生成的RT,避免数据库中积累大量无效令牌
- 每次使用旧RT换取新AT时,推荐同时颁发新的RT,并将旧RT标记为失效或直接删除,降低旧RT被滥用的风险
- 若完全不做限制,数据库会堆积大量无意义的过期/失效RT,增加存储成本和查询耗时
问题2:如何正确获取在线用户?
首先要明确「在线用户」的定义,再针对性处理:
- 如果是指当前可正常发起请求的活跃用户:
- 不能仅通过数据库中存在的RT判断,因为用户可能关闭浏览器后,RT仍在数据库但客户端已无令牌
- 建议在用户每次使用
access_token请求接口时,更新该用户的last_active_time字段 - 在线用户即为
last_active_time在设定阈值(比如15分钟)内,且对应RT未过期、未失效的用户
- 如果是指持有有效RT的用户:
- 可直接查询数据库中未过期、未被标记失效的RT关联的用户,但需注意这类用户可能实际已离线(如关闭浏览器)
- 补充:用户显式登出时要及时删除数据库中的对应RT,避免干扰在线状态判断
问题3:存储的Refresh Token会过期,何时从数据库移除?是否需要轮询数据库?
不需要轮询数据库,推荐以下更高效的清理方式:
- 数据库层面自动TTL清理:
- 利用数据库自带的过期自动删除功能:MySQL可通过事件调度器定期清理,PostgreSQL可使用pg_cron或TTL扩展,MongoDB直接支持文档级TTL配置,让过期RT自动被删除
- 懒清理策略:
- 每次处理RT校验、用户新登录、换取新AT等操作时,顺带清理该用户的过期RT
- 或在业务低峰时段(如凌晨)执行一次性批量清理脚本,删除所有过期的RT
- 轮询会持续消耗数据库资源,尤其是高并发场景,上述两种方式在性能和资源占用上更优
- 注意:生成RT时必须设置明确的过期时间,并将该时间存入数据库,这是所有清理方式的前提
内容的提问来源于stack exchange,提问作者mishy
相关产品推荐
相关产品推荐

