停止将 JSON Web Tokens 用于用户会话

开发者们正在争论 JSON Web Tokens(JWT)是否适合用于管理 Web 应用中的用户会话,尤其是单页应用。许多人认为问题不在 JWT 本身;真正的风险来自把它们存放在 JavaScript 可访问的位置(如 localStorage)、XSS 防护薄弱,以及 token 撤销困难,因此一些人更偏好传统的服务端会话,或将 JWT 存放在 HttpOnly、SameSite cookie 中。也有人指出 JWT 仍然适用于分布式系统和 API,但强调必须结合明确的威胁模型、较短的有效期和谨慎的实现,才能避免常见的安全陷阱。

争论范围

  • 许多人认为这篇文章真正讨论的是 XSS 和存储选择,而不是 JWT 本身。
  • 反复澄清:JWT 只是一种 token 格式;它既可以与 cookie 一起使用,也可以与其他存储方式一起使用,并不天然反对“基于 cookie 的会话”。

会话状态存放在哪里

  • 强势阵营:将会话标识符/JWT 存在 HttpOnlySecureSameSite cookie 中。
    • 可防止 XSS 直接窃取 token。
    • 避免手动处理请求头;浏览器会自动发送 cookie。
  • 对 localStorage / 可被 JS 访问的存储的批评:
    • 容易被 XSS 窃取;对长期有效的刷新 token 尤其有问题。
    • 一些框架(Firebase、Cognito)默认使用本地存储/IndexedDB,且无法使用 HttpOnly
  • 少数观点:localStorage “没问题”,因为一旦有 XSS 就“游戏结束”了,而且攻击者仍然可以通过浏览器内请求滥用 cookie。

CSRF、SameSite 和 Cookie

  • 建议:为敏感 cookie 设置 SameSite
    • Lax 通常被认为足以提供 CSRF 防护;Strict 可能会破坏首次页面登录后的行为。
  • 对跨站表单提交如何与 cookie 交互存在一些混淆;SameSite 被视为控制手段。

XSS 威胁模型

  • 一方认为:如果 JS 能被注入,攻击者已经可以冒充用户(发起请求),因此 cookie 与 localStorage 的差别不大。
  • 另一方认为:HttpOnly 仍然能显著限制损害,因为它能阻止 token 被窃取并在另一台设备上重用;分层防御很重要。

JWT 设计与撤销

  • 提到的 JWT 优势:
    • 无状态验证;适合 API、分布式系统和微服务。
    • 下游服务可以直接通过 JWT 授权,而无需每次都访问认证数据库。
  • 主要缺点:难以撤销 / 登出:
    • 常见模式:短期有效的访问 token + 长期有效的刷新 token,而刷新 token 通常是不透明的并需要数据库校验。
    • 一旦加入撤销列表或数据库检查,就失去了一些“无状态”优势;有人因此质疑在这种情况下为什么还要用 JWT。
  • 也有多人建议在 cookie 中使用简单的不透明会话 ID,仅在网关内部转换为 JWT。

法律 / UX / 实际问题

  • 澄清功能性/会话 cookie 通常不需要同意横幅;对“cookie 指令”的理解存在混淆。
  • 有人抱怨绝对化的安全建议(例如极短的超时时间)会损害可用性。
  • 也有人批评“停止使用 X”这类文章没有提供清晰、实用的替代方案或细致的区分。