4. JWT深入解析:JWT结构、签名算法与令牌选型

JWT(JSON Web Token)是现代分布式认证授权体系中最核心的令牌格式。理解JWT的结构、签名机制及其与Opaque Token的差异,是设计高可用、高安全SSO平台的基础。本节将从架构视角拆解JWT的每一层,并给出选型决策依据。

4.1 JWT结构:三段式令牌的构成

一个标准的JWT由三个Base64URL编码的部分组成,以点号(.)分隔:Header.Payload.Signature。每一段都承载着特定的语义和职责。

组成部分 位置 内容 是否加密 核心作用
Header(头部) 第一段 令牌类型(typ)和签名算法(alg) 仅Base64编码,明文 声明令牌类型和签名算法,供验证方解析
Payload(载荷) 第二段 声明(Claims):注册声明、公共声明、私有声明 仅Base64编码,明文 携带用户身份、权限、过期时间等业务数据
Signature(签名) 第三段 对Header和Payload的签名值 二进制签名数据 防篡改、验证令牌真实性
架构提示:JWT的Payload是明文可见的,任何拥有令牌的人都可以Base64解码查看内容。因此,绝对不要在Payload中存放密码、密钥、完整手机号等敏感信息。如需保护Payload内容,应使用JWE(JSON Web Encryption)进行加密。

4.1.1 Header(头部)

Header通常包含两个字段:typ(类型)和alg(签名算法)。示例:

{
  "alg": "RS256",
  "typ": "JWT"
}
  • typ:固定为"JWT",表示这是一个JWT令牌。
  • alg:签名算法标识,常见值包括HS256、RS256、ES256等。该字段决定了签名验证的数学原理。

4.1.2 Payload(载荷)

Payload包含三类声明(Claims):

声明类型 说明 示例
注册声明 预定义的标准字段,如iss(签发者)、sub(主题)、aud(受众)、exp(过期时间)、iat(签发时间) "exp": 1735689600
公共声明 在IANA注册或使用URI命名的自定义字段,避免冲突 "https://api.example.com/role": "admin"
私有声明 双方约定的自定义字段,不注册,仅内部使用 "user_id": "u12345"
安全警告:攻击者可能篡改exp(过期时间)或iat(签发时间)声明。必须依赖签名验证来确保这些声明未被修改。永远不要信任未经验签的JWT中的任何字段。

4.1.3 Signature(签名)

签名是对Header和Payload的完整性保护。生成过程如下:

signature = sign( base64url(header) + "." + base64url(payload), secret_or_private_key )

验证方使用相同的算法和密钥,对Header和Payload重新计算签名,并与令牌中的签名比对。若一致,则令牌未被篡改。

4.2 签名算法:HS256 vs RS256

签名算法是JWT安全性的基石。HS256和RS256是最常用的两种算法,它们在密钥管理、性能和安全模型上有本质区别。

核心区别:HS256使用对称密钥(同一个密钥既签名又验签),RS256使用非对称密钥对(私钥签名,公钥验签)。
对比维度 HS256(HMAC-SHA256) RS256(RSA-SHA256)
密钥类型 对称密钥(单一密钥) 非对称密钥对(私钥+公钥)
签名方 认证服务器(持有密钥) 认证服务器(持有私钥)
验证方 认证服务器(持有密钥) 任何服务(持有公钥)
密钥分发 需安全共享密钥给所有验证方 公钥可公开分发,无需保密
性能 签名和验签速度极快 签名较慢,验签较快
密钥轮换 需同步更新所有验证方,复杂度高 仅需更新认证服务器私钥,公钥可提前发布
适用场景 单体应用、内部微服务(验证方少且可控) 分布式系统、第三方API、SSO(验证方多且不可控)
架构避坑:在微服务架构中,如果使用HS256,每个微服务都必须持有相同的对称密钥。一旦某个服务被攻破,密钥泄露将导致整个系统的令牌可被伪造。RS256通过公钥验签,即使公钥泄露,也无法伪造令牌,安全性更高。

4.2.1 HS256 签名与验证流程

// 签名(认证服务器)
signature = HMAC-SHA256( base64url(header) + "." + base64url(payload), shared_secret )

// 验证(认证服务器或持有共享密钥的服务)
expected_signature = HMAC-SHA256( base64url(header) + "." + base64url(payload), shared_secret )
if signature == expected_signature: 验证通过

4.2.2 RS256 签名与验证流程

// 签名(认证服务器,使用私钥)
signature = RSA-SHA256( base64url(header) + "." + base64url(payload), private_key )

// 验证(任何服务,使用公钥)
expected_signature = RSA-SHA256( base64url(header) + "." + base64url(payload), public_key )
if signature == expected_signature: 验证通过

4.3 JWT vs Opaque Token:架构选型决策

Opaque Token(不透明令牌)是另一种常见的令牌格式,通常是一个随机字符串,本身不包含任何用户信息。JWT和Opaque Token各有优劣,选型取决于架构需求。

核心差异:JWT是自包含的令牌,验证方无需调用认证服务器即可验证;Opaque Token是引用型令牌,验证方必须调用认证服务器或令牌内省接口来获取用户信息。
对比维度 JWT(自包含令牌) Opaque Token(不透明令牌)
令牌内容 包含用户身份、权限、过期时间等结构化信息 随机字符串,无业务含义
验证方式 本地验签,无需网络调用 需调用认证服务器的内省(Introspection)接口
性能 高(无网络开销,本地计算) 低(每次验证都有网络延迟)
可撤销性 差(令牌签发后,在过期前无法主动撤销,除非维护黑名单) 好(服务端可随时删除令牌记录,实现即时撤销)
信息泄露风险 高(Payload明文,需避免存放敏感数据) 低(令牌本身无信息,用户数据在服务端)
令牌大小 较大(包含完整Payload) 小(通常16-32字节)
适用场景 高并发、低延迟、无状态API、分布式系统 高安全要求、需即时撤销、令牌生命周期短

4.3.1 架构选型建议

  • 优先选择JWT的场景:
    • 微服务架构,服务间需要无状态认证。
    • API网关需要快速验证令牌,避免每次转发都调用认证中心。
    • 令牌生命周期短(如15-30分钟),撤销需求不强烈。
  • 优先选择Opaque Token的场景:
    • 需要即时撤销用户会话(如用户主动登出、管理员封禁账号)。
    • 令牌生命周期长(如数小时或数天),撤销能力至关重要。
    • 令牌中需要携带大量敏感信息,但不想暴露给客户端。
混合架构实践:许多SSO平台采用双令牌模式:使用Opaque Token作为Refresh Token(长生命周期,可撤销),使用JWT作为Access Token(短生命周期,无状态验证)。这样既获得了JWT的高性能,又保留了Opaque Token的撤销能力。

4.4 JWT结构、签名与令牌选型全景图

下图展示了JWT的三段式结构、HS256与RS256的签名验证流程,以及JWT与Opaque Token在架构中的不同角色。

JWT结构、签名算法与令牌选型全景图 JWT结构、签名算法与令牌选型全景图 ① JWT三段式结构 Header alg: RS256, typ: JWT Payload sub, exp, iat, role Signature 防篡改签名值 . . Base64URL编码 Header.Payload.Signature ② 签名算法对比 HS256(对称密钥) 共享密钥 签名/验签 同一密钥 密钥需安全共享给所有验证方,轮换困难 RS256(非对称密钥对) 私钥(签名) 公钥(验签) 公钥可公开分发 私钥仅认证服务器持有,公钥可任意分发,轮换简单 ③ JWT vs Opaque Token 架构选型 JWT 验证流程(无状态) 客户端 API服务 本地验签 无需网络调用,高性能,但无法即时撤销 Opaque Token 验证流程(有状态) 客户端 API服务 内省接口 每次验证需网络调用,可即时撤销,安全性高

4.5 关键架构决策总结

  • 签名算法选型:在分布式SSO架构中,优先选择RS256。它允许每个微服务通过公开的公钥独立验证JWT,无需共享密钥,降低了密钥泄露风险。
  • 令牌格式选型:对于高并发、低延迟的API网关和微服务,使用JWT作为Access Token;对于需要即时撤销能力的Refresh Token,使用Opaque Token。
  • 安全底线:永远不要在JWT的Payload中存放敏感数据;始终验证签名;使用HTTPS传输令牌;设置合理的过期时间(建议Access Token 15-30分钟)。
架构师视角:JWT不是银弹。它的无状态特性带来了性能优势,但也牺牲了即时撤销能力。在SSO平台设计中,理解JWT的局限性并合理搭配Opaque Token,才能构建出既高性能又高安全的认证授权体系。