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

OAuth2 refresh_token刷新时生成新令牌而非复用现有令牌问题

问题根源

这是该OAuth2组件默认启用刷新令牌轮换机制的默认行为:默认配置下刷新令牌仅设置了相对过期时间,即每次签发新refresh_token时,过期时间都从当前签发时刻重新计算,没有绑定整个授权会话的绝对过期上限。只要用户在单次refresh_token过期前触发刷新,就能无限续期拿到有效令牌,导致永久登录状态。

可落地方案

方案1:配置刷新令牌绝对过期时间(推荐,符合OAuth2安全最佳实践)

无需修改核心业务代码,直接在组件配置中新增刷新令牌绝对TTL限制即可,注意区分两个时间配置的作用:

  • 单次refresh_token相对有效期:指单个refresh_token从签发到失效的时长,用于控制用户多久需要发起一次刷新请求
  • 授权会话绝对有效期:指从用户第一次授权成功开始,整个登录会话的最长存活时间,无论中间刷新多少次,到期后所有令牌强制失效

以Symfony框架下的YAML配置为例,其他框架适配的配置项逻辑完全一致:

league_oauth2_server:
    # access_token有效期,示例设为1小时
    access_token_ttl: PT1H
    # 单个refresh_token相对有效期,示例设为7天
    refresh_token_ttl: P7D
    # 授权会话绝对最长有效期,示例设为30天
    options:
        rotate_refresh_tokens: true
        revoke_old_refresh_tokens: true
        # 核心配置:强制所有轮换生成的refresh_token过期时间不超过首次授权的绝对时间点
        refresh_token_absolute_ttl: P30D

配置生效后,即使用户每次都在refresh_token到期前主动刷新,新生成的refresh_token过期时间也不会超出首次授权后30天的上限,到期后所有令牌自动失效,用户必须重新走登录流程。

方案2:自定义签发逻辑,联动自身会话规则

如果需要更灵活的过期控制(比如和用户的「记住我」选项、账号风险等级、管理员强制下线操作联动),可以通过组件提供的事件扩展点自定义逻辑:

  • 监听刷新令牌签发事件
  • 事件触发时,取出当前授权对应的用户标识、首次授权时间
  • 如果当前时间距离首次授权已经超过你设定的会话最长时长,直接拒绝签发新令牌,同时作废该用户名下所有有效refresh_token
  • 未超时则正常签发新令牌,也可根据业务规则动态调整本次签发的令牌有效期

方案3:关闭刷新令牌轮换(仅适合内部低安全场景,不推荐)

如果不需要刷新令牌轮换机制,可以直接关闭该功能,此时refresh_token只会在首次授权时签发一次,后续刷新access_token时不会生成新的refresh_token,直到这个固定的refresh_token到达预设过期时间自动失效:

league_oauth2_server:
    options:
        rotate_refresh_tokens: false

风险提示:该方案下refresh_token一旦被窃取,可在有效期内被无限次使用,存在明显安全隐患,生产环境公网服务不建议使用。

校验方法

配置完成后按以下步骤验证即可:

  1. 首次调用授权接口获取refresh_token,记录其过期时间点
  2. 间隔数分钟后用该refresh_token调用刷新接口,拿到新的refresh_token
  3. 检查新refresh_token的过期时间,应和首次获取的refresh_token的绝对过期点完全一致,不会向后顺延
  4. 到达绝对过期时间后,使用任意轮换生成的refresh_token调用刷新接口,都会返回invalid_grant错误,要求用户重新登录

内容的提问来源于stack exchange,提问作者Jigar Pancholi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 09:57:32