2. JWT 结构详解:Header、Payload、Signature 的组成与作用

JWT(JSON Web Token)是一种紧凑的、URL 安全的令牌表示方式,用于在各方之间以 JSON 对象的形式安全传输信息。一个标准的 JWT 由三个独立的部分组成,以点号(.)分隔:Header(头部)、Payload(载荷)、Signature(签名)。其典型结构如下:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
关键认知: JWT 的每一部分都是 Base64URL 编码后的字符串。Base64URL 编码与标准 Base64 编码类似,但将 + 替换为 -,将 / 替换为 _,并去除末尾的 =,使其可以安全地用于 URL 查询参数和 HTTP 头部。
JWT 三段式结构拆解图 JWT 三段式结构拆解 Header(头部) 算法 & 令牌类型 Base64URL 编码 . Payload(载荷) 声明(Claims)数据 Base64URL 编码 . Signature(签名) 防篡改验证 Base64URL 编码 最终 JWT 格式:Header.Payload.Signature 每一段都是独立可解码的 JSON 对象(签名除外)

2.1 Header(头部)

Header 是 JWT 的第一部分,通常包含两个主要字段:令牌类型(typ)和签名算法(alg)。它告诉接收方如何解析和验证这个令牌。

字段 含义 示例值 说明
alg 签名算法 HS256、RS256、ES256 必选字段。指定生成签名所使用的算法。HS256 为对称算法,RS256/ES256 为非对称算法。
typ 令牌类型 JWT 可选但推荐。声明该令牌为 JWT,帮助解析器快速识别。
cty 内容类型 JWT 可选。当 JWT 被嵌套签名或加密时使用,表示嵌套内容的类型。
性能关注点: alg 字段的选择直接影响鉴权性能。对称算法(如 HS256)计算速度快,但需要服务端和客户端共享密钥,在分布式系统中密钥分发困难。非对称算法(如 RS256)计算速度较慢(约慢 2-5 倍),但允许服务端只持有公钥,客户端持有私钥,更适合微服务架构。
// 一个典型的 Header 示例(解码后)
{
  "alg": "RS256",
  "typ": "JWT"
}
// Base64URL 编码后:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9

2.2 Payload(载荷)

Payload 是 JWT 的核心数据部分,包含一组声明(Claims)。声明是关于实体(通常是用户)和附加数据的陈述。JWT 规范定义了三种类型的声明:注册声明、公共声明、私有声明。

2.2.1 注册声明(Registered Claims)

这是一组预定义的、非强制但推荐使用的声明,提供互操作性。它们通常以三个字母的缩写表示。

声明 全称 含义 性能/安全影响
iss Issuer 签发者,标识签发 JWT 的实体 用于路由验证,减少跨域查询
sub Subject 主题,标识 JWT 所面向的用户 通常为用户 ID,影响查询索引效率
aud Audience 接收方,标识 JWT 的预期接收者 防止令牌被其他服务滥用
exp Expiration Time 过期时间(Unix 时间戳) 过期时间越短,验证频率越高,但安全性越好
nbf Not Before 生效时间(Unix 时间戳) 令牌在此时间之前不可用
iat Issued At 签发时间(Unix 时间戳) 用于计算令牌年龄和刷新策略
jti JWT ID 令牌唯一标识符 用于防止重放攻击,需配合服务端存储

2.2.2 公共声明(Public Claims)

公共声明由 IANA JSON Web Token Claims 注册表定义,或使用 URI 作为名称以避免冲突。例如:name、email、role。

2.2.3 私有声明(Private Claims)

私有声明是服务提供方自定义的字段,用于在通信双方之间共享特定数据。例如:department、permissions。

安全警告: Payload 仅经过 Base64URL 编码,并未加密。任何人都可以解码并读取其中的内容。切勿在 Payload 中存放密码、密钥、信用卡号等敏感信息。如果需要保护数据内容,应使用 JWE(JSON Web Encryption)。
// 一个典型的 Payload 示例(解码后)
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "exp": 1516242622,
  "role": "admin",
  "permissions": ["read:users", "write:users"]
}
// Base64URL 编码后:eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyNDI2MjIsInJvbGUiOiJhZG1pbiIsInBlcm1pc3Npb25zIjpbInJlYWQ6dXNlcnMiLCJ3cml0ZTp1c2VycyJdfQ

2.3 Signature(签名)

Signature 是 JWT 的第三部分,用于验证消息在传输过程中未被篡改,并确认 JWT 确实来自预期的签发者。签名的生成过程如下:

  1. 将 Base64URL 编码后的 Header 和 Payload 用点号(.)连接起来,形成签名输入字符串。
  2. 使用 Header 中指定的算法(alg)和一个密钥(对称或非对称)对上述字符串进行签名。
  3. 将生成的签名进行 Base64URL 编码,得到最终的 Signature 部分。
// 签名生成伪代码
signatureInput = base64UrlEncode(header) + "." + base64UrlEncode(payload)
signature = HMACSHA256(signatureInput, secretKey)  // 以 HS256 为例
signatureBase64 = base64UrlEncode(signature)
性能关键点: 签名验证是 JWT 鉴权中最耗时的操作。在分布式系统中,每次请求都需要验证签名。对于高并发场景,建议:
• 使用对称算法(HS256)时,将密钥缓存在本地内存,避免每次验证都读取配置中心。
• 使用非对称算法(RS256)时,缓存公钥并定期刷新,减少公钥获取的 I/O 开销。
• 考虑使用硬件安全模块(HSM)加速签名运算,但需评估成本与延迟。
JWT 签名生成与验证流程 JWT 签名生成与验证流程 签名生成(签发端) Header (Base64URL) Payload (Base64URL) . 签名输入字符串 密钥 签名算法(如 HMACSHA256) Signature (Base64URL) 签名验证(接收端) 接收到的 JWT:Header.Payload.Signature Header Payload Signature 重新生成签名输入 计算新签名 原签名 签名匹配?

2.4 三部分协同工作

JWT 的三个部分共同构成了一个自包含的令牌。服务端无需查询数据库即可验证用户身份:

  • Header 告诉服务端使用什么算法验证签名。
  • Payload 包含用户身份和权限信息,服务端直接从中提取数据。
  • Signature 确保 Header 和 Payload 未被篡改,并验证令牌来源。
性能优化建议: 在分布式鉴权场景中,建议将 Payload 的大小控制在 1KB 以内。过大的 Payload 会增加网络传输延迟和 Base64 编解码开销。对于需要携带大量权限信息的场景,可以考虑在 Payload 中只存放角色 ID,权限详情通过缓存或数据库按需加载。
部分 编码方式 是否加密 是否可篡改 主要作用
Header Base64URL 否 是(被签名保护) 声明算法和类型
Payload Base64URL 否 是(被签名保护) 携带用户声明数据
Signature Base64URL 否 否(篡改后验证失败) 验证完整性和来源