2. JWT 结构解析:Header、Payload、Signature 的组成与作用
JWT(JSON Web Token)是一种紧凑的、自包含的认证授权契约载体。其结构由三个独立的部分通过 点号(.) 连接而成,每一部分都承担着特定的安全与语义职责。理解这三部分的组成与作用,是掌握 JWT 认证授权契约边界的基础。
核心公式: JWT = Base64Url(Header) + "." + Base64Url(Payload) + "." + Signature
2.1 整体结构概览
一个完整的 JWT 字符串示例如下:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
以下表格展示了 JWT 三个部分的名称、编码方式与核心作用:
| 部分 | 编码方式 | 是否加密 | 核心作用 |
|---|---|---|---|
| Header(头部) | Base64Url | 否(明文可见) | 声明令牌类型与签名算法 |
| Payload(载荷) | Base64Url | 否(明文可见) | 携带用户身份与授权声明数据 |
| Signature(签名) | 算法生成 | 是(防篡改) | 验证令牌完整性、防伪造 |
安全警示: Header 和 Payload 仅经过 Base64Url 编码,并非加密。任何持有令牌的人都可以解码读取其中的内容。切勿在 Payload 中存放密码、密钥等敏感信息。
2.2 Header(头部)—— 契约的元数据声明
Header 是 JWT 的元数据部分,通常包含两个标准字段:
- alg(Algorithm): 签名或加密算法,如
HS256(HMAC-SHA256)、RS256(RSA-SHA256)、none(无签名,禁止生产环境使用)。 - typ(Type): 令牌类型,固定为
JWT。
一个典型的 Header 解码后如下:
{
"alg": "HS256",
"typ": "JWT"
}
Header 的作用在于告知验证方:该令牌使用了何种算法进行签名,从而验证方可以选取对应的密钥或公钥进行校验。如果攻击者篡改 alg 为 none,而服务端未做校验,则可能导致签名绕过漏洞。
2.3 Payload(载荷)—— 契约的声明内容
Payload 是 JWT 的核心数据区,包含三类声明(Claims):
| 声明类型 | 说明 | 示例字段 |
|---|---|---|
| 注册声明(Registered Claims) | 预定义的标准字段,非强制但推荐使用 | iss(签发者)、sub(主题)、aud(受众)、exp(过期时间)、iat(签发时间) |
| 公共声明(Public Claims) | 自定义字段,需在 IANA JSON Web Token Registry 注册或使用命名空间避免冲突 | https://example.com/is_admin |
| 私有声明(Private Claims) | 双方协商的自定义字段,不注册 | user_id、role、permissions |
一个典型的 Payload 解码后如下:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"exp": 1516242622,
"role": "admin"
}
最佳实践: Payload 的大小直接影响网络传输性能。仅存放必要的身份标识与授权声明,避免存放大量业务数据。建议 Payload 总大小控制在 1KB 以内。
2.4 Signature(签名)—— 契约的防伪印章
Signature 是 JWT 完整性的保障。它通过对 Header 和 Payload 进行签名运算生成,确保令牌在传输过程中未被篡改。签名生成过程如下:
- 将 Header 和 Payload 分别进行 Base64Url 编码。
- 将编码后的两部分用点号连接:
base64UrlEncode(header) + "." + base64UrlEncode(payload)。 - 使用 Header 中声明的算法(如 HMAC-SHA256)和密钥(secret)对上述字符串进行签名。
- 将生成的签名进行 Base64Url 编码,附加到令牌末尾。
签名验证的伪代码如下:
// 签名生成(服务端签发时)
signature = HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
// 签名验证(服务端接收时)
expectedSignature = HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
if (signature === expectedSignature) {
// 令牌未被篡改,信任 Payload 内容
} else {
// 令牌无效,拒绝请求
}
2.5 JWT 结构关系图
下图展示了 JWT 三个部分的生成流程与依赖关系:
2.6 关键安全要点总结
- 签名不可伪造: 只要密钥不泄露,攻击者无法在篡改 Payload 后重新生成有效签名。
- 内容不保密: Header 和 Payload 是明文编码,敏感信息必须加密传输或使用 JWE(JSON Web Encryption)。
- 算法固定: 服务端应白名单允许的签名算法,拒绝
none算法,防止算法混淆攻击。 - 过期校验: 必须校验
exp(过期时间)声明,防止令牌被无限期重放。
契约边界视角: JWT 的 Signature 是认证授权契约的“数字印章”。Header 声明契约规则(算法),Payload 承载契约内容(声明),Signature 确保契约不可篡改。三者共同构成了一个自洽、可验证的认证授权单元。