2、JWT结构解析:Header头部、Payload载荷、Signature签名的组成与作用
JWT(JSON Web Token)是一种紧凑的、URL安全的令牌表示方式,其核心结构由三个独立的部分通过点号(.)连接而成:Header(头部)、Payload(载荷)和Signature(签名)。理解这三部分的组成与作用,是设计安全、可靠的JWT接口契约的基础。
关键认知:JWT 的每一部分都是 Base64URL 编码后的 JSON 字符串。整个令牌的格式为
xxxxx.yyyyy.zzzzz。任何一部分被篡改,签名验证都会失败。
2.1 JWT 整体结构概览
下图展示了 JWT 的完整结构,以及三个组成部分在令牌中的位置关系。
2.2 Header(头部)—— 算法与类型声明
Header 是 JWT 的第一部分,通常包含两个关键字段:令牌类型(typ)和签名算法(alg)。它是服务端验证签名的“说明书”。
2.2.1 标准字段
| 字段 | 含义 | 必选 | 常见值 |
|---|---|---|---|
alg |
签名或加密算法 | 是 | HS256、RS256、ES256、none |
typ |
令牌类型 | 否 | JWT |
kid |
密钥标识 | 否 | 字符串,用于多密钥场景 |
2.2.2 典型示例
// 原始 JSON
{
"alg": "HS256",
"typ": "JWT"
}
// Base64URL 编码后
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
安全警告:切勿在生产环境中使用
"alg": "none"。攻击者可能通过篡改 Header 中的算法为 none 来绕过签名验证。服务端必须强制校验 alg 字段为预期的安全算法。
2.3 Payload(载荷)—— 声明数据
Payload 是 JWT 的第二部分,包含实际传递的声明(Claims)。声明是关于实体(通常是用户)和附加数据的陈述。Payload 虽然经过 Base64URL 编码,但并未加密,因此不应存放敏感信息。
2.3.1 声明分类
| 类别 | 说明 | 示例 |
|---|---|---|
| 注册声明 | 预定义的标准字段,提供互操作性 | iss、sub、aud、exp、nbf、iat、jti |
| 公共声明 | 在 IANA JSON Web Token Registry 中注册或使用防冲突命名 | https://api.example.com/role |
| 私有声明 | 服务提供方和消费方之间自定义的字段 | user_id、department |
2.3.2 核心注册声明详解
| 声明 | 全称 | 类型 | 作用 |
|---|---|---|---|
iss |
Issuer | 字符串 | 签发者,标识签发 JWT 的服务方 |
sub |
Subject | 字符串 | 主题,标识 JWT 所代表的用户或实体 |
aud |
Audience | 字符串或数组 | 接收方,标识此 JWT 的目标服务 |
exp |
Expiration Time | 数字(Unix时间戳) | 过期时间,在此时间之后 JWT 无效 |
nbf |
Not Before | 数字(Unix时间戳) | 生效时间,在此时间之前 JWT 无效 |
iat |
Issued At | 数字(Unix时间戳) | 签发时间 |
jti |
JWT ID | 字符串 | 唯一标识,用于防止重放攻击 |
2.3.3 典型示例
// 原始 JSON
{
"iss": "https://auth.example.com",
"sub": "user_123456",
"aud": "https://api.example.com",
"exp": 1735689600,
"iat": 1735603200,
"role": "admin",
"department": "engineering"
}
// Base64URL 编码后
eyJpc3MiOiJodHRwczovL2F1dGguZXhhbXBsZS5jb20iLCJzdWIiOiJ1c2VyXzEyMzQ1NiIsImF1ZCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tIiwiZXhwIjoxNzM1Njg5NjAwLCJpYXQiOjE3MzU2MDMyMDAsInJvbGUiOiJhZG1pbiIsImRlcGFydG1lbnQiOiJlbmdpbmVlcmluZyJ9
设计建议:Payload 中只存放非敏感的身份标识和权限信息。密码、信用卡号、个人隐私数据等绝对不应出现在 JWT 的 Payload 中。如需传递敏感数据,应使用 JWE(JSON Web Encryption)进行加密。
2.4 Signature(签名)—— 完整性与防篡改
Signature 是 JWT 的第三部分,用于验证消息在传输过程中未被篡改,并确认 JWT 确实由持有正确密钥的签发者生成。签名过程将 Header 和 Payload 作为输入,结合密钥和指定算法计算得出。
2.4.1 签名生成过程
- 将 Header 和 Payload 分别进行 Base64URL 编码。
- 将编码后的 Header 和 Payload 用点号(.)连接,形成签名输入字符串。
- 使用 Header 中指定的算法和密钥,对输入字符串进行签名。
- 将生成的签名进行 Base64URL 编码,作为 JWT 的第三部分。
2.4.2 签名验证流程
2.4.3 签名算法对比
| 算法 | 类型 | 密钥 | 性能 | 适用场景 |
|---|---|---|---|---|
HS256 |
对称(HMAC + SHA256) | 单一共享密钥 | 高 | 单一服务内部,或信任的微服务之间 |
RS256 |
非对称(RSA + SHA256) | 私钥签名,公钥验证 | 中 | 分布式系统、第三方应用、开放平台 |
ES256 |
非对称(ECDSA + SHA256) | 私钥签名,公钥验证 | 高 | 移动端、IoT 设备、对性能要求高的场景 |
最佳实践:在微服务架构或开放 API 场景中,优先使用 RS256 或 ES256 非对称算法。这样,资源服务只需持有公钥即可验证 JWT,无需与认证服务共享私密密钥,大大降低了密钥泄露的风险。
2.5 三部分协作关系总结
JWT 的三个部分各司其职,共同构成了一个自包含、可验证的身份令牌:
- Header:告诉验证方“我是用什么算法签名的”。
- Payload:告诉验证方“我携带了哪些用户信息和权限”。
- Signature:证明“我确实是合法签发者签发的,并且内容没有被篡改过”。
任何对 Header 或 Payload 的修改,都会导致重新计算的签名与原始签名不一致,从而被服务端拒绝。这种机制使得 JWT 可以在不依赖服务端会话存储的情况下,安全地在客户端和服务端之间传递身份信息。