当前位置: 首页 > news >正文

安全的 Token 刷新机制:Refresh Token 轮换与权限实时同步

安全的 Token 刷新机制:Refresh Token 轮换与权限实时同步

在现代 Web 应用中,基于 JWT 的无状态认证广泛使用。然而,为了兼顾安全性和用户体验,通常采用双 Token 机制(Access Token + Refresh Token)。本文将详细阐述如何安全地实现 Refresh Token 的存储、轮换,并确保权限变更能实时生效。

一、核心原则

  • Refresh Token 以 SessionId 为唯一标识:每个会话对应一个 Refresh Token
  • Refresh Token 可重复使用:在有效期内可多次刷新 Access Token
  • Access Token 必须反映用户当前状态:刷新时应重新加载用户最新角色和权限
  • Refresh Token 应持久化存储:因其低频使用,适合存入数据库

二、Refresh Token 数据库表设计

由于 Refresh Token 使用频率低,将其存储在关系型数据库中是安全且高效的选择。以下是推荐的表结构:

CREATETABLErefresh_tokens(idBIGINTPRIMARYKEYAUTO_INCREMENT,session_idVARCHAR(128)NOTNULLUNIQUECOMMENT'会话唯一标识',user_idVARCHAR(64)NOTNULL,token_hashVARCHAR(255)NOTNULLCOMMENT'Refresh Token 的 BCrypt 哈希值',device_infoVARCHAR(500)COMMENT'设备或浏览器信息',login_channelVARCHAR(50)COMMENT'登录渠道:web/app/wechat等',ip_addressVARCHAR(45),created_atDATETIMENOTNULLDEFAULTCURRENT_TIMESTAMP,expires_atDATETIMENOTNULL,revokedBOOLEANDEFAULTFALSECOMMENT'是否已被撤销',last_used_atDATETIME,use_countINTDEFAULT0COMMENT'使用次数统计',INDEXidx_user_id(user_id),INDEXidx_session_id(session_id),INDEXidx_token_hash(token_hash),INDEXidx_expires_at(expires_at));

字段说明:

  • session_id:会话唯一标识,用于管理特定设备/浏览器的登录状态
  • login_channel:区分登录来源(Web端、App、小程序等)
  • use_count:统计 Refresh Token 被使用的次数

三、完整实现流程

1. 用户登录

  • 验证用户名/密码
  • 生成唯一session_id(UUID)
  • 生成 Access Token(含当前角色)和 Refresh Token
  • 将 Refresh Token 信息存入refresh_tokens
  • 返回 Token 对和session_id给客户端

2. 刷新 Access Token(关键步骤)

  1. 客户端发送session_id+ Refresh Token 到/auth/refresh
  2. 服务端根据session_id查询对应的 Refresh Token 记录
  3. 验证 Refresh Token 是否有效(未过期、未撤销、哈希匹配)
  4. 重新从用户服务加载用户最新信息(包括角色、启用状态等)
  5. 若用户已被禁用或删除,拒绝刷新
  6. 生成新的 Access Token(基于最新权限)
  7. 使用原有 Refresh Token(不重新生成)
  8. 更新使用次数和最后使用时间
  9. 返回新 Access Token 给客户端

3. 用户登出

  • 客户端调用/auth/logout并传入session_id
  • 服务端根据session_id将对应 Refresh Token 标记为已撤销

四、时序图:完整的 Token 刷新流程

http://www.jsqmd.com/news/94240/

相关文章:

  • 护眼灯排名前十的品牌有哪些?年度权威榜单出炉,护眼效果超强!
  • kanass全面介绍(11) - 如何进行迭代管理
  • 基于模型预测控制的ACC巡航车队仿真:Matlab与CarSim的完美结合
  • 如何安全迁移至PHP 8.6?揭秘企业级兼容性测试流程与工具推荐
  • sward全面介绍(10) - 如何做好文档评审
  • 多模态缓存清理全解析,Laravel 13开发者必须掌握的3种高阶技巧
  • 软件开发全流程注意事项:避坑指南与效率提升
  • 创业团队用 XinServer 提升项目交付效率实战
  • 从传感器到图表:PHP实现农业数据实时可视化的5个关键步骤
  • 杰理之获取返回的当前时间与实际播放的音频时间并不一致【篇】
  • 一文详解Java中死锁产生原因、常见场景及排查解决思路(附详细案例代码)
  • 开放土壤光谱库:建立可复制的土壤校准模型(PLOS ONE,2025)
  • 在前端中list.map的用法
  • 【Dubbo从入门到精通:架构解析与实战落地】
  • Geo优化【双核四驱】驱动企业增长:权威专家于磊深度解析
  • 6G真的要来了?中国移动这次把“未来网络”摆到了台前
  • Yandex复杂还原验证码识别
  • sward全面介绍(11) - 如何有效保障文档的安全可靠
  • Google Vids:由AI驱动的工作视频创作 | ProductHunt 今日热榜 - 12月15日
  • 【专家亲授】低代码环境下PHP组件动态更新的8个最佳实践
  • Python中的直接赋值、浅拷贝与深拷贝:常见错误案例与深入理解
  • 基于Matlab/simulink的双电机建模驱动控制仿真模型:探索纯电与混动汽车世界
  • App项目后台如何用 XinServer 实现智能缓存机制?
  • 中海达“天空地水工”一体化监测体系,赋能安徽水利数字化变革
  • 黄金成色怎么看?新手第一次买金,别只盯着“亮不亮”
  • 自动驾驶—CARLA仿真(10)tutorial_gbuffer demo
  • 【技术教程】Qoder使用技巧分享
  • 半导体设备报警诊断程序技术方案
  • Transformer模型详解系列:Qwen-Image背后的MMDiT架构原理
  • 15000行C++代码,我实现了一个完整的JVM虚拟机(含GC和JIT)