领域建模驱动后端合规边界与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 用于验证消息在传输过程中未被篡改,并确保令牌的完整性。签名过程如下:
- 将 Base64URL 编码后的 Header 和 Payload 用点号连接。
- 使用 Header 中指定的算法(如 HMAC-SHA256)和密钥(Secret)对上述字符串进行加密。
- 将生成的签名进行 Base64URL 编码。
// 伪代码示例
signature = HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
安全警示: Payload 仅经过 Base64URL 编码,并未加密。任何持有令牌的人都可以解码查看其内容。切勿在 Payload 中存放密码、信用卡号等敏感信息。如需加密,应使用 JWE(JSON Web Encryption)。
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 的“无状态”特性也意味着服务端无法主动终止会话,这在合规审计场景中可能成为弱点。
4.2.1 核心差异深度解析
- 状态存储位置: Session 是“有状态”的,服务端必须维护一个会话存储;JWT 是“无状态”的,所有用户信息都编码在令牌中,服务端只需验证签名。
- 扩展性: 在微服务架构中,JWT 的“无状态”特性使得每个服务都可以独立验证令牌,无需访问共享 Session 存储,极大简化了水平扩展。
- 安全性考量: Session 的敏感数据在服务端,客户端仅持有随机 ID,安全性更高;JWT 的 Payload 仅 Base64 编码,必须假设其内容可被客户端读取,因此绝不能存放密码、密钥等敏感信息。
- 吊销能力: Session 可以立即删除服务端记录实现强制下线;JWT 在签发后直到过期前都有效,服务端无法主动使其失效,必须配合黑名单或短过期时间(如 15 分钟)加刷新令牌机制来弥补。
合规风险提示: 在金融、医疗等强合规领域,如果选择 JWT 作为认证方案,必须设计令牌刷新和黑名单机制,以满足“用户主动注销后令牌立即失效”的合规要求。同时,JWT 的 Payload 中不应包含任何个人敏感信息(如身份证号、银行卡号),否则可能违反数据最小化原则。