领域建模驱动后端合规边界与JWT令牌安全策略设计 - 第4节

4.1 JWT 结构:Header、Payload、Signature

JSON Web Token(JWT)是一种紧凑的、URL 安全的令牌格式,用于在各方之间以 JSON 对象的形式安全传输声明信息。一个 JWT 由三个 Base64URL 编码的部分组成,以点号(.)分隔:Header.Payload.Signature。

核心公式: JWT = Base64URL(Header) + "." + Base64URL(Payload) + "." + HMACSHA256(Base64URL(Header) + "." + Base64URL(Payload), Secret)

4.1.1 Header(头部)

Header 通常包含两部分信息:令牌类型(typ)和签名算法(alg)。

  • typ(Type): 声明令牌类型,固定为 "JWT"。
  • alg(Algorithm): 签名算法,如 HS256(HMAC-SHA256)、RS256(RSA-SHA256)等。
{
  "alg": "HS256",
  "typ": "JWT"
}

4.1.2 Payload(载荷)

Payload 包含声明(Claims),即关于实体(通常是用户)和附加数据的 JSON 对象。声明分为三类:

声明类型 说明 常见字段
注册声明(Registered Claims) 预定义的标准字段,非强制但推荐使用 iss(签发者)、sub(主题)、aud(受众)、exp(过期时间)、iat(签发时间)
公共声明(Public Claims) 在 IANA JSON Web Token Registry 中注册或使用防冲突命名空间 如 "https://api.example.com/role"
私有声明(Private Claims) 自定义字段,用于在双方之间共享特定数据 如 "user_id": 12345, "department": "engineering"
{
  "sub": "1234567890",
  "name": "张三",
  "iat": 1516239022,
  "exp": 1516242622,
  "role": "admin"
}

4.1.3 Signature(签名)

Signature 用于验证消息在传输过程中未被篡改,并确保令牌的完整性。签名过程如下:

  1. 将 Base64URL 编码后的 Header 和 Payload 用点号连接。
  2. 使用 Header 中指定的算法(如 HMAC-SHA256)和密钥(Secret)对上述字符串进行加密。
  3. 将生成的签名进行 Base64URL 编码。
// 伪代码示例
signature = HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)
安全警示: Payload 仅经过 Base64URL 编码,并未加密。任何持有令牌的人都可以解码查看其内容。切勿在 Payload 中存放密码、信用卡号等敏感信息。如需加密,应使用 JWE(JSON Web Encryption)。
JWT 结构分解图 JWT 结构分解图 Header {"alg":"HS256", "typ":"JWT"} Base64URL 编码 eyJhbGciOiJIUzI1NiIs InR5cCI6IkpXVCJ9 Payload {"sub":"123", "name":"张三", "exp":1516242622} Base64URL 编码 eyJzdWIiOiIxMjMiLC JuYW1lIjoi5byg5LiJIn0 Signature HMACSHA256( header + "." + payload, secret) Base64URL 编码 SflKxwRJSMeKKF2QT 4fwpMeJf36POk6yJV 最终 JWT 字符串:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV

4.2 JWT 与 Session 的区别

JWT 和 Session 是两种主流的身份认证与状态管理机制,它们在存储位置、扩展性、安全性等方面存在本质差异。理解这些差异对于设计合规的后端架构至关重要。

对比维度 Session(服务端会话) JWT(JSON Web Token)
状态存储位置 服务端(内存、Redis、数据库) 客户端(令牌自身携带状态)
扩展性(水平扩展) 需要共享 Session 存储(如 Redis 集群),复杂度高 天然无状态,服务端无需共享存储,易于扩展
跨域/跨服务支持 受限于 Cookie 同源策略,跨域需额外配置 通过 HTTP Header 传递,天然支持跨域和微服务
令牌/ID 大小 Session ID 通常很小(如 32 字节) JWT 包含完整声明,体积较大(通常 500-2000 字节)
吊销机制 直接删除服务端 Session 即可立即失效 无法主动吊销,需配合黑名单或短过期时间
安全性 敏感数据存储在服务端,客户端仅持有随机 ID Payload 仅 Base64 编码,不可存放敏感信息;需防重放攻击
典型应用场景 传统单体应用、对实时吊销要求高的系统 分布式系统、微服务、移动端、单点登录(SSO)
架构决策建议: 在领域驱动设计(DDD)的上下文中,JWT 更适合作为跨限界上下文(Bounded Context)的令牌传递机制,因为它不依赖共享存储。但需注意,JWT 的“无状态”特性也意味着服务端无法主动终止会话,这在合规审计场景中可能成为弱点。
JWT 与 Session 认证流程对比 JWT 与 Session 认证流程对比 Session 认证流程 客户端 服务端 Session 存储 ① 登录请求 ② 创建 Session ③ 返回 Session ID 后续请求携带 Cookie(Session ID) ④ 请求 + Cookie ⑤ 查询 Session JWT 认证流程 客户端 服务端 ① 登录请求 ② 生成 JWT ③ 返回 JWT 后续请求携带 Authorization: Bearer JWT ④ 请求 + JWT ⑤ 验证签名 (无状态,无需存储)

4.2.1 核心差异深度解析

  • 状态存储位置: Session 是“有状态”的,服务端必须维护一个会话存储;JWT 是“无状态”的,所有用户信息都编码在令牌中,服务端只需验证签名。
  • 扩展性: 在微服务架构中,JWT 的“无状态”特性使得每个服务都可以独立验证令牌,无需访问共享 Session 存储,极大简化了水平扩展。
  • 安全性考量: Session 的敏感数据在服务端,客户端仅持有随机 ID,安全性更高;JWT 的 Payload 仅 Base64 编码,必须假设其内容可被客户端读取,因此绝不能存放密码、密钥等敏感信息。
  • 吊销能力: Session 可以立即删除服务端记录实现强制下线;JWT 在签发后直到过期前都有效,服务端无法主动使其失效,必须配合黑名单或短过期时间(如 15 分钟)加刷新令牌机制来弥补。
合规风险提示: 在金融、医疗等强合规领域,如果选择 JWT 作为认证方案,必须设计令牌刷新和黑名单机制,以满足“用户主动注销后令牌立即失效”的合规要求。同时,JWT 的 Payload 中不应包含任何个人敏感信息(如身份证号、银行卡号),否则可能违反数据最小化原则。