跳转至

Deep Research: [70] JWT(RFC 7519):令牌不是字符串,是可审计的契约

  • Source: https://www.rfc-editor.org/rfc/rfc7519
  • Note: ../notes/ref-070-jwt.md
  • Snapshot: ../sources/md/www-rfc-editor-org-rfc-rfc7519-7bb6aaba0f31.md
  • Category: User / Auth / Audit (user_auth)
  • Chapters: 09-backend, 11-user

TL;DR

JWT 不仅仅是一串用于传递的字符,它是一份经过数字签名、防篡改的、自包含的身份与权限契约。它的核心价值在于通过标准化的声明(Claims)将认证逻辑从中心化数据库查询下放到端侧/服务侧校验,是现代分布式架构和 AI Agent 交互中无状态信任的基石。

核心观点

  1. 自包含的信任状(Self-contained):JWT 内部携带了关于主体的所有必要信息(用户 ID、角色、过期时间),服务接收方无需回查中心数据库即可完成鉴权,这对于微服务和高并发 AI 推理场景至关重要。
  2. 声明即逻辑(Claims define Logic):RFC 7519 定义了 iss(签发者)、sub(主体)、aud(受众)、exp(过期时间)等标准字段。验证 JWT 实际上就是在验证这些字段是否符合当下的业务上下文(契约履行)。
  3. 签名非加密(Signed != Encrypted):标准 JWT(JWS)仅保证内容未被篡改,载荷(Payload)只是 Base64 编码,默认是公开透明的。切勿在未加密的 JWT 中放入密码、手机号等敏感隐私。
  4. 受众限制(Audience Restriction)aud 字段极其关键但常被忽略。它指定了令牌的合法使用者,防止发给服务 A的令牌被恶意重放到服务 B使用。
  5. 不可撤销性悖论:由于 JWT 的无状态特性,一旦签发,在 exp 到期前理论上一直有效。必须配合黑名单机制或短期 Token + 长期 Refresh Token策略来解决注销和封禁问题。
  6. 算法协商的陷阱:JWT 头部包含加密算法字段(如 HS256, RS256),但验证方绝不能盲目信任头部指定的算法(特别是要防御 alg: none 攻击),必须强制指定允许的算法列表。

可落地做法

1. 产品定义(第 3、11 章)

  • 定义有效期策略:区分访问令牌(Access Token,建议 5-15 分钟)和刷新令牌(Refresh Token,建议 7-30 天)。前者用于高频 API 调用,后者用于静默续期。
  • 最小化字段:只放入系统通用的 ID(如 user_idtenant_id)和权限范围(scopes),避免放入变动频繁的业务数据(如 vip_level),以免数据变更导致令牌数据陈旧。

2. 工程实现(第 7、9 章)

  • 强制校验三要素:所有网关或验证中间件必须校验 exp(是否过期)、iss(是否由可信服务签发)、alg(是否为预期算法)。
  • 密钥管理:对称加密(HS256)仅适用于单体应用;微服务或对外开放 API 应使用非对称加密(RS256/ES256),私钥签发,公钥验证。
  • 解决注销延迟:在 Redis 中维护一个基于 jti(JWT ID)或 user_id 的失效时间戳或黑名单,在网关层做轻量级阻断。

3. 评测与安全(第 18 章)

  • 安全扫描:测试将 header 中的 alg 修改为 none,移除签名部分,检查接口是否报错。
  • 过期测试:构造已过期的 Token,验证接口返回 401 而非 500 或 200。

检查清单:JWT 安全实现

  • [ ] 算法白名单:验证器代码中是否硬编码了允许的算法(如 RS256),并拒绝 none
  • [ ] 强校验过期:是否开启了严格的 exp 校验,并处理了时钟偏差(Clock Skew,通常允许 30-60 秒误差)?
  • [ ] 敏感信息隔离:Payload 中是否不包含任何 PII(个人敏感信息)或机密数据?
  • [ ] 受众检查:如果令牌用于特定服务,是否校验了 aud 字段匹配当前服务标识?
  • [ ] 密钥强度:HMAC 密钥长度是否至少 256 位?RSA 密钥长度是否至少 2048 位?
  • [ ] 传输安全:JWT 是否强制仅通过 HTTPS 传输?(防止中间人窃取令牌)
  • [ ] 日志脱敏:应用日志中是否对 JWT 进行了脱敏处理(仅记录 jti 或掩码处理)?

常见坑与对策

  • :把 JWT 当 Session 用,一旦用户修改密码或被封禁,手里的旧 JWT 依然有效。
    • 对策:引入版本号或最后修改时间戳。在签发 JWT 时写入 iat(签发时间),验证时检查该用户在 DB/缓存中的 last_logout_time,若 iat < last_logout_time 则拒绝。
  • :令牌体积过大,导致 HTTP Header 超限。
    • 对策:控制 Payload 大小,不要把全量的用户 Profile 或权限树塞进去。仅放角色 ID 或权限组 ID。
  • :多个环境(Dev/Prod)共用密钥。
    • 对策:严格隔离不同环境的密钥(Secret/Keypair),防止开发环境泄漏导致生产环境被伪造。

可用于丰富《AI 辅助软件产品》的写作点

  • 第 5 章(MVP 后端骨架):在讲解 API 鉴权时,通过 RFC 7519 引入标准化的 Token 结构。对比传统 Session与JWT在 AI 流式响应(WebSocket/SSE)中的优势(减少握手时的数据库压力)。
  • 第 10 章(Agent 架构与 RAG)Agent 间的信任传递。当 Agent A 调用 Agent B 时,如何通过 JWT 的 audscope 声明,实现细粒度的工具调用权限控制(例如:只允许搜索工具,不允许删除文件工具)。
  • 第 11 章(用户模块与审计):利用 jti(JWT ID)构建全链路可观测性。将 jti 注入到所有微服务的 Trace Context 中,实现从用户点击到底层 LLM 调用的完整审计链路。
  • 第 17 章(部署与运维):介绍 Sidecar 模式(如 Envoy/Istio)如何利用 JWT 的标准结构(JWKS 协议)在网关层统一处理认证,让业务代码纯粹化。