0

0

Django Simple JWT刷新令牌轮换与页面刷新冲突的解决方案

DDD

DDD

发布时间:2025-11-09 10:08:12

|

1050人浏览过

|

来源于php中文网

原创

django simple jwt刷新令牌轮换与页面刷新冲突的解决方案

在使用Django Simple JWT实现用户认证时,开启刷新令牌轮换(ROTATE_REFRESH_TOKENS)和旧令牌黑名单(BLACKLIST_AFTER_ROTATION)可能导致快速页面刷新时,旧刷新令牌在新令牌到达客户端前被列入黑名单,从而引发认证问题。本教程将阐述一种可靠的策略,通过解耦页面刷新与令牌刷新机制,并采用同步令牌刷新处理访问令牌过期,以及引导用户重新认证处理刷新令牌过期,来确保用户体验的流畅与系统的安全性。

1. Django Simple JWT令牌轮换机制的挑战

Django Simple JWT通过配置ROTATE_REFRESH_TOKENS: True和BLACKLIST_AFTER_ROTATION: True,旨在提高安全性,每次使用刷新令牌获取新的访问令牌时,都会生成一个新的刷新令牌,并将旧的刷新令牌列入黑名单。这种机制在正常操作下非常有效,但当用户在极短时间内多次刷新页面时,可能会出现竞态条件:

  1. 用户刷新页面。
  2. 前端发送请求,使用旧的刷新令牌获取新的访问令牌和刷新令牌。
  3. 后端处理请求,生成新的令牌对,并将旧的刷新令牌列入黑名单。
  4. 在新的刷新令牌成功发送并存储到客户端之前,用户再次刷新页面。
  5. 前端再次发送请求,但此时使用的仍然是已被黑名单的旧刷新令牌,导致认证失败。

这种场景尤其容易在前端采用持久化登录,且令牌作为HTTP-only cookie发送时发生。

2. 理解JWT认证令牌流

为了更好地解决上述问题,我们需要明确JWT认证的令牌流:

  • 访问令牌(Access Token):用于访问受保护资源,生命周期较短,通常通过HTTP-only cookie发送。
  • 刷新令牌(Refresh Token):用于在访问令牌过期后获取新的访问令牌,生命周期较长,也应通过HTTP-only cookie发送。

正常的认证流程是:

  1. 用户登录成功后,后端签发访问令牌和刷新令牌,并分别存储在HTTP-only cookie中。
  2. 前端在后续请求中,通过浏览器自动携带的访问令牌(从cookie中)访问后端API。
  3. 当访问令牌过期时,后端返回401 Unauthorized响应。

3. 核心策略:解耦页面刷新与令牌刷新

解决上述竞态条件的关键在于:页面刷新不应该触发令牌刷新。

3.1 页面刷新:仅使用现有Access Token

当用户刷新页面或关闭浏览器后重新打开时,前端应依赖于HTTP-only cookie中已存在的访问令牌进行认证。浏览器会自动在请求中携带这个访问令牌。后端接收并验证该令牌。

  • 如果访问令牌有效,后端正常处理请求。
  • 如果访问令牌已过期,后端应返回 401 Unauthorized 状态码

3.2 Access Token过期处理:同步刷新机制

当后端因访问令牌过期返回 401 Unauthorized 时,前端需要执行令牌刷新。为了避免在多个并发请求同时失败时,触发多次刷新令牌的请求(这可能再次引发竞态条件),前端应实现一个同步令牌刷新机制

实现思路:

聚好用AI
聚好用AI

可免费AI绘图、AI音乐、AI视频创作,聚集全球顶级AI,一站式创意平台

下载
  1. 当任何API请求收到 401 Unauthorized 响应时,不要立即发送刷新令牌请求。
  2. 将所有因 401 失败的待处理请求挂起。
  3. 检查是否已有刷新令牌的请求正在进行中。
    • 如果没有,则发起一个刷新令牌的请求。
    • 如果有,则将当前请求加入到等待队列中。
  4. 刷新令牌请求成功后(获取到新的访问令牌和刷新令牌),使用新的访问令牌重试所有挂起的请求。
  5. 刷新令牌请求失败(例如,刷新令牌本身已过期或无效)时,清除所有挂起请求,并引导用户重新登录。

这种机制确保了即使有多个视图同时请求数据并发现访问令牌过期,也只会发起一次刷新令牌的操作,从而有效避免了刷新令牌轮换可能带来的冲突。

3.3 Refresh Token过期处理:重新认证

刷新令牌也有其生命周期,最终也会过期。当刷新令牌过期或无效时:

  1. 前端尝试刷新令牌的请求将失败。
  2. 后端通常会返回一个特定的错误,例如OAuth 2.0规范中的 invalid_grant 错误代码。
  3. 前端捕获到此错误后,应清除所有本地存储的用户会话信息,并重定向用户到登录页面进行重新认证。这是用户重新建立会话的唯一方式。

4. 关于前端手动拉黑令牌的考量

原始问题中提到了一种可能的修复方案:禁用自动黑名单,并在前端收到新刷新令牌后,发送一个包含旧刷新令牌的请求到后端进行手动黑名单处理。

@api_view(['POST'])
def blacklist_token(request):
    refreshToken = request.data.get("refresh")
    print(refreshToken)
    if refreshToken:
        token = tokens.RefreshToken(refreshToken)
        token.blacklist()
    return Response(status=status.HTTP_200_OK)

虽然这种方法在理论上可行,但它将黑名单的责任从后端转移到了前端,增加了前端的复杂性,并且仍然可能面临一些挑战:

  • 可靠性问题:前端请求是否总能成功发送?网络中断或前端应用崩溃是否会导致旧令牌无法被及时黑名单?
  • 安全风险:如果旧刷新令牌在未被黑名单前泄露,其有效期会更长。
  • 竞态条件:如果用户在收到新令牌并发送黑名单请求之间再次触发了使用旧令牌的请求,仍然可能出现问题。

相比之下,上述推荐的解耦页面刷新和令牌刷新,并采用同步刷新机制的策略更为健壮和符合JWT认证的最佳实践。

5. 最佳实践与可靠性测试

为了确保应用程序的可靠性,强烈建议对各种令牌过期事件进行充分的测试和演练:

  • 访问令牌过期测试:模拟访问令牌过期后,前端是否能正确触发同步刷新,并成功重试挂起的请求。
  • 刷新令牌过期测试:模拟刷新令牌过期后,前端是否能正确检测到 invalid_grant 错误,并引导用户重新登录。
  • 并发请求测试:在访问令牌即将过期时,同时发送多个API请求,观察同步刷新机制是否能有效工作。
  • 快速页面刷新测试:在启用令牌轮换的情况下,快速多次刷新页面,验证用户是否能保持登录状态。

通过这些测试,可以确保您的Django Simple JWT认证系统在各种边缘情况下都能提供稳定可靠的用户体验。

总结

解决Django Simple JWT刷新令牌轮换与快速页面刷新导致的认证冲突,核心在于重新审视令牌的使用逻辑。页面刷新应直接利用现有访问令牌,而非触发令牌刷新。当访问令牌过期时,前端应实施一个同步刷新机制来获取新的令牌。而当刷新令牌最终过期时,则需引导用户重新进行认证。这种策略不仅能有效避免竞态条件,还能提升系统的整体安全性和用户体验的流畅性。

相关专题

更多
cookie
cookie

Cookie 是一种在用户计算机上存储小型文本文件的技术,用于在用户与网站进行交互时收集和存储有关用户的信息。当用户访问一个网站时,网站会将一个包含特定信息的 Cookie 文件发送到用户的浏览器,浏览器会将该 Cookie 存储在用户的计算机上。之后,当用户再次访问该网站时,浏览器会向服务器发送 Cookie,服务器可以根据 Cookie 中的信息来识别用户、跟踪用户行为等。

6414

2023.06.30

document.cookie获取不到怎么解决
document.cookie获取不到怎么解决

document.cookie获取不到的解决办法:1、浏览器的隐私设置;2、Same-origin policy;3、HTTPOnly Cookie;4、JavaScript代码错误;5、Cookie不存在或过期等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

339

2023.11.23

阻止所有cookie什么意思
阻止所有cookie什么意思

阻止所有cookie意味着在浏览器中禁止接受和存储网站发送的cookie。阻止所有cookie可能会影响许多网站的使用体验,因为许多网站使用cookie来提供个性化服务、存储用户信息或跟踪用户行为。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

404

2024.02.23

cookie与session的区别
cookie与session的区别

本专题整合了cookie与session的区别和使用方法等相关内容,阅读专题下面的文章了解更详细的内容。

88

2025.08.19

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6070

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

794

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1054

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

1185

2024.03.01

Golang 分布式缓存与高可用架构
Golang 分布式缓存与高可用架构

本专题系统讲解 Golang 在分布式缓存与高可用系统中的应用,涵盖缓存设计原理、Redis/Etcd集成、数据一致性与过期策略、分布式锁、缓存穿透/雪崩/击穿解决方案,以及高可用架构设计。通过实战案例,帮助开发者掌握 如何使用 Go 构建稳定、高性能的分布式缓存系统,提升大型系统的响应速度与可靠性。

53

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 8.2万人学习

CSS3 教程
CSS3 教程

共18课时 | 4.4万人学习

Vue 教程
Vue 教程

共42课时 | 6.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号