2. JWT 结构深度解析:Header、Payload、Signature 三部分详解
JWT(JSON Web Token)是一种紧凑的、URL 安全的令牌表示方式,其核心结构由三个独立的部分组成:Header(头部)、Payload(载荷)和 Signature(签名)。这三部分通过 Base64URL 编码后,以点号(.)分隔拼接成最终的令牌字符串。
JWT 令牌结构示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
2.1 Header(头部)
Header 是一个 JSON 对象,通常包含两个标准字段:令牌类型(typ)和签名算法(alg)。它是 JWT 的元数据描述部分,用于告知解析方如何验证该令牌。
| 字段 | 含义 | 常见值 |
|---|---|---|
alg |
签名或加密算法 | HS256、RS256、ES256、none |
typ |
令牌类型 | JWT |
cty |
内容类型(嵌套 JWT 时使用) | JWT |
// 未编码的 Header 示例
{
"alg": "HS256",
"typ": "JWT"
}
2.2 Payload(载荷)
Payload 是 JWT 的核心数据部分,包含 声明(Claims)。声明分为三类:注册声明(Registered Claims)、公共声明(Public Claims)和私有声明(Private Claims)。Payload 本身是明文编码,不包含敏感信息。
| 声明类型 | 说明 | 示例字段 |
|---|---|---|
| 注册声明 | 预定义的标准字段,非强制但推荐使用 | iss(签发者)、sub(主题)、exp(过期时间)、iat(签发时间) |
| 公共声明 | 在 IANA JSON Web Token Claims 注册表中定义的字段 | email、name、preferred_username |
| 私有声明 | 自定义字段,由双方协商使用 | role、permissions、tenant_id |
// 未编码的 Payload 示例
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"exp": 1516242622,
"role": "admin"
}
安全警告:Payload 仅经过 Base64URL 编码,未加密。任何持有令牌的人都可以解码查看其内容。严禁在 Payload 中存放密码、密钥、身份证号等敏感数据。
2.3 Signature(签名)
Signature 是对 Header 和 Payload 的完整性保护。它使用 Header 中指定的算法,结合一个密钥(Secret)或私钥(Private Key)对前两部分进行签名计算。签名确保令牌在传输过程中未被篡改,并验证签发者的身份。
// 签名生成公式(以 HMAC-SHA256 为例)
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
2.4 Base64URL 编码原理
JWT 使用 Base64URL 编码而非标准 Base64,主要为了解决 URL 安全传输问题。标准 Base64 包含 +、/ 和 = 字符,这些字符在 URL 中有特殊含义,可能导致解析错误。
| 编码方式 | 字符集 | 填充字符 | URL 安全 |
|---|---|---|---|
| 标准 Base64 | A-Z、a-z、0-9、+、/ |
= |
否 |
| Base64URL | A-Z、a-z、0-9、-、_ |
无(去除填充) | 是 |
Base64URL 转换规则:
- 将
+替换为-(减号) - 将
/替换为_(下划线) - 去除末尾的
=填充字符
// Base64URL 编码示例(Python)
import base64
def base64url_encode(data):
return base64.urlsafe_b64encode(data).rstrip(b'=').decode()
# 输入: b'{"alg":"HS256","typ":"JWT"}'
# 输出: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
2.5 JWT 与 JWS / JWE 的关系
JWT 是一个抽象概念,其具体实现由 JWS(JSON Web Signature)和 JWE(JSON Web Encryption)两个规范定义。理解三者的关系是掌握 JWT 安全边界的关键。
| 规范 | 全称 | 核心功能 | 是否加密 Payload | 典型场景 |
|---|---|---|---|---|
| JWT | JSON Web Token | 令牌抽象定义 | — | 概念层 |
| JWS | JSON Web Signature | 签名保护(完整性 + 认证) | 否(明文) | 访问令牌、ID 令牌 |
| JWE | JSON Web Encryption | 加密保护(机密性) | 是(密文) | 敏感数据传输 |
实践要点:绝大多数分布式鉴权场景使用 JWS 格式的 JWT。JWE 由于性能开销和密钥管理复杂度较高,仅在 Payload 包含高度敏感数据时使用。在微服务架构中,建议优先使用 JWS + HTTPS 的组合,而非直接使用 JWE。
2.6 完整 JWT 结构总结
一个完整的 JWT(JWS 格式)由三个 Base64URL 编码的字符串通过点号连接而成:
// JWT 结构公式
JWT = Base64URL(Header) + "." + Base64URL(Payload) + "." + Base64URL(Signature)
// 实际令牌示例
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
关键结论:
- Header 和 Payload 仅做 Base64URL 编码,不加密,任何人都可解码查看。
- Signature 使用密钥对前两部分进行签名,防止篡改。
- JWT 是抽象概念,实际使用中几乎都是 JWS 格式。
- Base64URL 通过替换
+//和去除=实现 URL 安全传输。