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

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

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

上述字符串中,第一部分是Base64URL编码后的Header,第二部分是Base64URL编码后的Payload,第三部分是使用指定算法和密钥生成的Signature。

JWT 令牌结构示意图 Header(头部) 算法 & 令牌类型 {"alg":"HS256","typ":"JWT"} Base64URL 编码 . Payload(载荷) 声明(Claims) {"sub":"123","name":"John"} Base64URL 编码 . Signature(签名) 防篡改验证 HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

2.1 Header(头部)

Header 是 JWT 的第一部分,通常包含两个关键字段:令牌类型(typ)和签名算法(alg)。它使用 Base64URL 编码,但请注意:Base64URL 编码不是加密,任何人都可以解码查看其内容。

字段 含义 示例值 说明
alg 签名算法(Algorithm) HS256、RS256、ES256 指定生成签名所使用的算法,是验证令牌完整性的核心
typ 令牌类型(Type) JWT 声明该令牌为 JWT,帮助解析器识别
cty 内容类型(Content Type) JWT(可选) 当 JWT 嵌套使用时,声明内部结构类型

常见算法对比:

  • HS256(HMAC with SHA-256):对称加密,签名和验证使用同一个密钥。适合单一服务内部使用。
  • RS256(RSA with SHA-256):非对称加密,使用私钥签名、公钥验证。适合微服务间或第三方认证。
  • ES256(ECDSA with SHA-256):基于椭圆曲线的非对称算法,密钥更短,性能更高。
// 原始 Header JSON
{
  "alg": "HS256",
  "typ": "JWT"
}

// Base64URL 编码后
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

2.2 Payload(载荷)

Payload 是 JWT 的第二部分,包含实际要传递的声明(Claims)。声明是关于实体(通常是用户)和附加数据的陈述。Payload 同样使用 Base64URL 编码,不提供机密性保护,因此绝对不要在此存放密码、密钥等敏感信息。

声明分为三类:

类别 字段 全称 说明
注册声明
(Registered Claims)
iss Issuer 签发者,标识签发该 JWT 的实体
sub Subject 主题,通常为用户的唯一标识
aud Audience 接收方,标识该 JWT 的目标受众
exp Expiration Time 过期时间,UNIX 时间戳,过期后令牌无效
nbf Not Before 生效时间,在此之前令牌不可用
iat Issued At 签发时间,UNIX 时间戳
jti JWT ID 令牌唯一标识,用于防止重放攻击
公共声明
(Public Claims)
自定义 — 在 IANA JSON Web Token Registry 中注册或使用防冲突命名空间(如 URL)
私有声明
(Private Claims)
自定义 — 双方约定使用的自定义字段,不注册,需避免命名冲突
// 原始 Payload JSON
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "role": "admin",
  "permissions": ["read", "write", "delete"]
}

// Base64URL 编码后
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJyb2xlIjoiYWRtaW4iLCJwZXJtaXNzaW9ucyI6WyJyZWFkIiwid3JpdGUiLCJkZWxldGUiXX0

最佳实践:Payload 中只存放必要的最小信息,如用户 ID、角色、权限范围。避免存放完整的用户对象或敏感数据。对于需要保密的信息,应使用 JWE(JSON Web Encryption)进行加密。

2.3 Signature(签名)

Signature 是 JWT 的第三部分,用于验证令牌在传输过程中未被篡改,并确认发送者的身份。签名由以下三部分通过指定算法计算得出:

  1. 编码后的 Header
  2. 编码后的 Payload
  3. 一个密钥(Secret)

签名生成公式(以 HS256 为例):

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

验证过程:接收方使用相同的密钥和算法,对接收到的 Header 和 Payload 重新计算签名,然后与令牌中的签名进行比较。如果一致,则令牌未被篡改;否则令牌无效。

JWT 签名生成与验证流程 签名生成(服务端) Base64URL(Header) Base64URL(Payload) + 密钥(Secret) ↓ HMACSHA256 算法 签名验证(接收端) Base64URL(Header) Base64URL(Payload) + 密钥(Secret) ↓ HMACSHA256 算法 比较

2.4 三部分协同工作

JWT 的三个部分各司其职,共同构建了一个安全、可验证的身份令牌:

  • Header 告诉系统“用什么算法”来验证签名。
  • Payload 告诉系统“谁在请求”以及“有什么权限”。
  • Signature 确保 Header 和 Payload 没有被篡改,并且确实由可信的签发者生成。

安全警告:

  • 永远不要在 JWT 的 Payload 中存储密码、密钥、信用卡号等敏感信息。
  • 始终验证 alg 字段,防止算法混淆攻击(攻击者将 RS256 改为 HS256 并使用公钥作为密钥验证)。
  • 设置合理的 exp(过期时间),避免令牌长期有效。
  • 使用 HTTPS 传输 JWT,防止中间人截获。

2.5 完整 JWT 示例

以下是一个包含三个部分的完整 JWT 令牌及其解码后的内容:

// 完整 JWT
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJyb2xlIjoiYWRtaW4ifQ.tXU1VZq0X5Z0X5Z0X5Z0X5Z0X5Z0X5Z0X5Z0X5Z0

// 解码后的 Header
{
  "alg": "HS256",
  "typ": "JWT"
}

// 解码后的 Payload
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "role": "admin"
}

// 签名(二进制,不可读)
[HMACSHA256 计算结果]