jwt auth dead cover
26

6 月

JWT 没有死:2026 年 Web 认证该选 Session、JWT 还是混合方案

可引用摘要: JWT 是一种声明格式,不是完整的登录、会话或授权方案。对同源 Web 应用,服务端 Session 配合安全 Cookie 通常更容易撤销和管理;对跨服务 API、第三方授权或分布式资源服务器,短期 JWT 仍然有价值。安全选型的重点不是“JWT 还是 Cookie”二选一,而是令牌存放位置、有效期、撤销机制、签名验证、刷新令牌保护和业务架构是否匹配。

“JWT 已死”是一个吸引点击但容易误导的结论。JWT 仍被 OAuth、OpenID Connect 和大量 API 系统使用;真正发生变化的是,工程团队越来越少把长期 JWT 当成无需服务端状态的万能会话方案。

更准确的问题应该是:你的系统为什么需要 JWT,它解决了什么边界问题,又由什么机制承担撤销、轮换和泄漏后的响应?

先分清四个容易混淆的概念

概念作用常见误解
Cookie浏览器存储并随请求发送数据的机制Cookie 不等于 Session,也不等于天然安全
Session服务端维护的会话状态Session ID 仍是凭证,被窃取后同样可能遭到冒用
JWT以 JSON 表达声明的令牌格式JWT 不等于 OAuth,也不保证加密
OAuth 2.0委托授权框架OAuth 不规定所有 access token 都必须是 JWT

JWT 可以放在 Cookie 中,Session ID 也可以通过 Cookie 传输。把“JWT vs Cookie”作为二选一,本身就混合了令牌格式和传输机制两个层次。

JWT 的真实风险是什么

已签名不等于已加密

常见的 JWS 形式 JWT 使用 Base 64 URL 编码 Header 和 Payload,并用签名保证完整性。拿到令牌的人通常可以读取其中声明,因此不应把密码、身份证号、密钥或其他不必要的敏感信息放入 Payload。

但不能因此说所有 JWT 都“只能明文”。JOSE 体系也定义了 JWE 加密令牌。实际系统应明确自己使用的是签名 JWT、加密 JWT,还是不透明令牌。

长有效期令牌难以及时撤销

如果资源服务器仅验证 JWT 签名和过期时间,不查询服务器状态,那么令牌在过期前通常会继续有效。登出、封号、权限回收和密钥泄漏都会因此变得复杂。

常见缓解措施包括:缩短 access token 有效期、维护 denylist、使用令牌内省、轮换密钥、绑定会话版本,或者把高风险操作重新交给服务端状态检查。引入这些机制并不说明 JWT “失败”,而是说明无状态验证存在明确代价。

算法与声明验证必须显式配置

alg: none 和算法混淆问题通常来自验证器错误接受未授权算法,而不是 JWT 必然允许攻击者绕过签名。RFC 8725 要求调用方限制允许的算法,并验证 issuer、audience、subject、过期时间等声明。

使用成熟库也不能代替配置。应用必须明确允许算法、密钥来源和声明约束,不能相信令牌自己声明的验证方式。

存放位置决定一部分攻击面

把 access token 放入 localStorage 会让同源脚本读取它,一旦发生 XSS,令牌可能被直接窃取。HttpOnly Cookie 可以阻止 JavaScript 读取,但浏览器会自动附带 Cookie,因此还需要 SameSite、CSRF 防护、Secure、作用域和会话更新策略。

不存在“换成 Session Cookie 就没有任何令牌泄漏风险”的方案。Session ID 仍是 bearer credential,必须保护传输、存储和生命周期。

三种常见架构如何选

同源传统 Web 应用:优先考虑服务端 Session

如果浏览器和后端属于同一产品,服务端可以稳定访问共享 Session 存储,并且业务需要即时登出、封号和权限回收,那么不透明随机 Session ID 往往最简单。

建议至少做到:

  • 使用足够随机、不可预测的 Session ID;
  • Cookie 设置 HttpOnlySecure 和合适的 SameSite
  • 登录和权限提升后更新 Session ID;
  • 设置空闲与绝对过期时间;
  • 在登出、改密和安全事件后撤销会话;
  • 不把敏感业务数据直接写入客户端 Cookie。

跨服务 API:短期 JWT 可以减少同步查询

当多个资源服务器需要验证同一个授权服务器签发的声明时,短期 JWT 可以减少每次请求的中心化查询,并让服务独立验证签名。

代价是需要严格管理 issuer、audience、scope、密钥轮换和撤销窗口。JWT 应保持短期、最小权限,并避免承载经常变化的权限数据。

浏览器 OAuth 客户端:优先评估 BFF 或安全刷新机制

对于浏览器应用,Backend-for-Frontend(BFF)模式可以把 OAuth token 保留在服务端,仅向浏览器发送受保护的会话 Cookie。如果业务必须向公共客户端签发 refresh token,RFC 9700 要求使用发送者约束或 refresh token rotation 来检测重放。

这项要求来自 OAuth 2.0 Security Best Current Practice,而不是“OAuth 2.1 已经正式淘汰 JWT”。OAuth 2.1 在本文核验时仍属于持续演进的规范工作,不能把草案状态写成已生效的最终标准。

如果团队正在把认证能力接入 Agent 或工具协议,还可以结合智盒的MCP 与 AI 基础设施观察评估信任边界;涉及 Codex 与应用开发流程时,可参考ChatGPT 与 Codex 集成观察

一张可执行的决策表

场景优先方案需要额外确认
同源网站、单一后端服务端 Session + 安全 CookieSession 存储、高可用、CSRF 与撤销
多个内部资源服务短期 JWT 或不透明 token + introspectionaudience、scope、密钥轮换、撤销窗口
第三方 API 授权标准 OAuth/OIDC 流程客户端类型、PKCE、token 绑定与最小权限
浏览器 SPA优先评估 BFFXSS、CSRF、刷新令牌存放方式
高风险即时权限变更服务端状态检查或短期 token封号、改密、支付等事件如何立刻生效

适合与不适合

适合

  • 正在为新 Web 应用选择认证架构的开发团队;
  • 需要审查现有长期 JWT、localStorage 或刷新令牌方案的人;
  • 希望区分 Session、Cookie、JWT 与 OAuth 职责边界的工程师。

不适合

  • 把本文当作针对具体系统的渗透测试或合规认证;
  • 不结合威胁模型就直接复制固定的 token 有效期;
  • 用“JWT 已死”或“Session 永远更安全”替代架构评估。

FAQ

JWT Payload 是否任何人都能读取?

常见的签名 JWT 可以被持有者解码读取,但签名可以防止未授权篡改。JWE 可以提供加密。无论使用哪种形式,都不应放入不必要的敏感数据。

JWT 是否无法撤销?

JWT 格式本身没有自动撤销机制,但系统可以通过短有效期、denylist、令牌内省、会话版本或密钥策略实现撤销。问题在于这些措施会增加状态和复杂度。

Session Cookie 是否天然比 JWT 安全?

不是。安全性取决于随机性、Cookie 属性、CSRF/XSS 防护、传输安全、会话固定防护、过期和撤销策略。被窃取的 Session ID 同样可能被重放。

Access token 应该设置成 5 分钟还是 15 分钟?

没有适用于所有系统的固定答案。有效期应结合数据敏感度、刷新机制、用户体验、撤销能力和攻击检测速度确定,并通过威胁模型记录理由。

refresh token rotation 能阻止所有令牌盗用吗?

不能。它主要用于检测旧 refresh token 的重放,并在发现重复使用时撤销令牌族。它不能替代 TLS、安全存储、客户端绑定、XSS 防护和异常检测。

官方参考来源


本文由 AI(Codex)基于公开来源整理并完成结构化核验,发布由智盒运营流程执行。


RELATED

Posts