← [ BACK_TO_NOTES ]

JWT

JWT 是一种自包含的结构化 Token 格式;重点在签名、claims、验证边界,以及它与 Access Token、Refresh Token、Session 和 Authorization 的区别。

#security #concept #growing #jwt

[!info] related notes

JWT

一句话定义

JWT(JSON Web Token)是一种把 claims 放进结构化载荷,并通过签名/MAC 保护完整性与签发关系的 Token 格式。

最重要的边界是:

JWT 是凭证格式,不是 Session,不是 Access Token 的同义词,也不是一整套认证架构。

结构

JWT 常见三段:

Header.Payload.Signature
  • Header:算法、类型等元数据;
  • Payload:sub、exp、iat、iss、aud、scope 等 claims;
  • Signature:验证 Header + Payload 是否被篡改,以及是否来自持有对应密钥的一方。

Payload 通常只是 Base64URL 编码,不是机密加密区。敏感秘密不应该因为“放进 JWT”就认为被隐藏。

签名不是加密

验证 JWT 通常是:

parse
+
verify signature
+
validate exp / nbf / iss / aud / allowed alg

而不是“解密 JWT”。

只有 JWE 等加密 Token 才涉及机密性;普通签名 JWT 主要解决完整性与来源验证。

JWT 能直接证明什么

签名和 claims 校验通过,可以支持:

  • Token 在签发后未被篡改;
  • Token 来自被信任的签发方;
  • Token 仍在自身时间窗口内;
  • aud、iss、scope 等满足当前验证规则。

JWT 不能天然证明什么

它不能单独证明:

  • 数据库用户现在仍存在;
  • 用户没有刚被封禁;
  • 某个长期 Session / Grant 仍然 live;
  • 用户 Role 没有变化;
  • 用户仍然拥有某个具体资源;
  • Token 没有被盗取后重放。

因此:

JWT cryptographic validity
≠
current session liveness
≠
resource authorization

JWT 与 Access Token

Access Token 是“拿来访问 API 的凭证角色”;JWT 是“凭证格式”。

所以:

Access Token
→ 可以是 JWT
→ 也可以是 opaque token

短期 Access JWT 的一个重要价值是:Resource Server 可以本地验证签名和 claims,不必每次回 Auth Server 或 Session Store。

JWT 与 Refresh Token

Refresh Token 也可以做成 JWT,但完全没有必须这样做。

很多系统更倾向:

opaque random Refresh Token
→ 服务端保存 hash / family / session mapping
→ refresh 时检查 revoke / expiry / rotation

因为 Refresh Token 本质上需要很强的生命周期控制,而“它是否自包含”并不是最核心的问题。

两种 JWT + Session 组合不要混为一谈

模式 A:每请求都查 Session

JWT
→ verify
→ read session_id claim
→ lookup Session
→ allow / deny

优点是 Session revoke 可以即时生效;代价是每次请求都依赖 Session Store,因此 JWT 的无状态快路径价值较小。

模式 B:Hybrid 短期 Access JWT

普通 API:
Access JWT
→ local verify
→ 不查 Session Store

Refresh / Logout / Revoke:
Refresh Token
→ Auth Server
→ check Session / Grant

这种模式让长期生命周期有状态,而高频访问走短期无状态快路径。

如果 Session 在 Access JWT 签发后被撤销,已签发 Token 可能继续有效到 exp;短 TTL 的意义就是限制这个 stale window。

撤销是 JWT 的核心架构取舍

纯 Stateless JWT 一旦签发,在 exp 前很难精确立即撤销某一个 Token。

常见策略:

  • 缩短 Access Token TTL;
  • 使用 Refresh Token + Server-side Grant;
  • blacklist / denylist;
  • token version;
  • 对敏感操作额外检查实时 Session/User 状态。

一旦每个请求都必须查询 revoke/session 状态,系统就不再是纯 Stateless;这不是错误,而是用实时控制换取额外状态依赖。

Claims 不是数据库实时真相

例如 JWT 中有:

{
  "sub": "42",
  "role": "admin",
  "exp": 1234567890
}

这只表示签发时或签发方认可的 claims 快照。

如果 Role 在数据库中随后变更,而 Resource Server 不重新查询,那么 JWT 中的旧 Role 会存在到 Token 过期。

因此不要把长生命周期 JWT 当成长期业务状态同步机制。

验证安全边界

  • 明确限制允许的 alg,不要盲信 Token Header;
  • 验证 exp / nbf 等时间约束;
  • 按场景验证 iss 和 aud;
  • 密钥要有轮换策略;
  • 不把敏感秘密放在可读 Payload;
  • Bearer JWT 一旦泄露,在有效期内通常可被持有者使用。

常见误区

  • “JWT 是加密字符串” → 常见 JWT 是签名,不是加密。
  • “能 decode 就合法” → decode 只是解析,必须 verify。
  • “JWT = Access Token” → JWT 是格式,Access Token 是角色。
  • “Refresh Token 必须 JWT” → 不需要。
  • “JWT 一定无状态” → 是否无状态取决于服务端是否查询 Session/revocation 状态。
  • “JWT 验证成功就完成授权” → 资源级 Authorization 仍可能依赖数据库当前状态。
  • “JWT 比 Session 更现代” → 不是同一层概念,不能这样比较。

最短记忆

JWT 是一个可签名验证的 claims 容器。Access/Refresh 决定 Token 做什么,Session 决定长期登录状态是否存在,Authorization 决定当前用户能不能操作当前资源。

学习检查

不看正文回答:

  1. JWT 是“认证方案”、Token 角色,还是一种结构化凭证格式?
  2. 普通签名 JWT 的 Payload 为什么不能当作机密数据区?
  3. decode 与 verify 的安全语义有什么根本不同?
  4. 为什么 JWT 签名验证成功只能证明 claims 的完整性/签发关系,不能证明当前 Session 一定仍然有效?
  5. Access Token 与 Refresh Token 为什么都“可以是 JWT”,但不“必须是 JWT”?
  6. Pure Stateless JWT 的精确撤销为什么困难?常见补偿策略有哪些?
  7. 一个用户刚被封禁但旧 Access JWT 尚未过期时,系统是否仍可能接受它?这取决于什么架构选择?

掌握验收

  • 能区分 JWT、Access Token、Refresh Token、Session、Authorization 五个层次;
  • 能完整说明签名、claims 验证、撤销与 stale window;
  • 能根据业务实时性要求选择纯 Stateless、每请求查 Session 或 Hybrid 路线。
创建于 2026/1/24 更新于 2026/9/30
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本