3. JWT Header 详解:类型声明与签名算法
JWT(JSON Web Token)的 Header(头部)是令牌的第一部分,承载着令牌的元数据。它通常由两个核心字段组成:typ(类型声明)和 alg(签名算法)。Header 最终会经过 Base64URL 编码,成为 JWT 的第一段字符串。
3.1 Header 结构概览
一个标准的 JWT Header 是一个 JSON 对象,示例如下:
{
"typ": "JWT",
"alg": "HS256"
}
该 JSON 对象经过 Base64URL 编码后,形如:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9。
3.2 typ 类型声明
typ(Type)字段用于声明令牌的媒体类型。在 JWT 规范中,该字段的值通常固定为 JWT,表示这是一个 JSON Web Token。
| 字段 | 含义 | 常见值 | 说明 |
|---|---|---|---|
typ |
令牌类型 | JWT |
明确标识该令牌遵循 JWT 规范 |
cty |
内容类型 | JWT(嵌套 JWT 时使用) |
当 JWT 的 payload 本身又是一个 JWT 时使用 |
最佳实践:在 SaaS 多租户系统中,
typ 字段应始终设置为 JWT,以确保网关和鉴权中间件能够正确识别令牌格式。
3.3 alg 签名算法详解
alg(Algorithm)字段指定了用于签名或加密 JWT 的算法。这是 Header 中最重要的字段,直接决定了令牌的安全性和性能。SaaS 系统中常用的算法分为两类:对称算法和非对称算法。
3.3.1 HS256(HMAC with SHA-256)
- 类型:对称签名算法
- 密钥:使用同一个密钥进行签名和验证
- 性能:计算速度快,适合高并发场景
- 适用场景:单体应用、内部服务间通信、信任域内的微服务
- 安全风险:密钥泄露会导致整个系统被伪造令牌攻击
3.3.2 RS256(RSA with SHA-256)
- 类型:非对称签名算法
- 密钥对:使用私钥签名,公钥验证
- 性能:签名速度较慢,验证速度较快
- 适用场景:分布式系统、第三方应用授权、跨信任域通信
- 安全优势:私钥仅由签发方持有,公钥可安全分发
| 对比维度 | HS256 | RS256 |
|---|---|---|
| 算法类型 | 对称 | 非对称 |
| 密钥管理 | 单一密钥,需保密 | 私钥保密,公钥公开 |
| 签名速度 | 快 | 慢 |
| 验证速度 | 快 | 快 |
| 密钥分发 | 困难(需安全通道) | 容易(公钥可任意分发) |
| 典型场景 | 内部服务、单体应用 | 开放 API、第三方集成 |
安全警告:在生产环境中,禁止使用
alg: "none"。攻击者可以通过修改 Header 中的 alg 为 none 来绕过签名验证,这是 JWT 安全中最常见的漏洞之一。
3.4 Header 的 Base64URL 编码
JWT Header 在传输前必须进行 Base64URL 编码。Base64URL 是标准 Base64 的变体,专门为 URL 安全而设计。
3.4.1 编码规则
- 将 JSON 对象序列化为字符串
- 使用 Base64 编码
- 将
+替换为- - 将
/替换为_ - 去除末尾的
=(填充字符)
3.4.2 编码示例
// 原始 JSON
{"typ":"JWT","alg":"HS256"}
// 标准 Base64
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
// Base64URL(无变化,因为不含 + 和 /)
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
关键区别:Base64URL 编码后的字符串不包含
+、/ 和 = 字符,可以直接安全地放在 URL 的查询参数或 HTTP Header 中,无需额外 URL 编码。
3.5 JWT Header 结构图
下图展示了 JWT Header 的组成、编码过程及其在完整 JWT 中的位置:
3.6 常见算法标识符速查表
| alg 参数值 | 算法名称 | 算法类型 | 推荐场景 |
|---|---|---|---|
HS256 |
HMAC with SHA-256 | 对称 | 内部服务、单体应用 |
HS384 |
HMAC with SHA-384 | 对称 | 更高安全要求的内部通信 |
HS512 |
HMAC with SHA-512 | 对称 | 最高安全要求的内部通信 |
RS256 |
RSA with SHA-256 | 非对称 | 分布式系统、第三方授权 |
RS384 |
RSA with SHA-384 | 非对称 | 更高安全要求的分布式系统 |
RS512 |
RSA with SHA-512 | 非对称 | 最高安全要求的分布式系统 |
ES256 |
ECDSA with P-256 | 非对称 | 移动端、IoT 设备(密钥更短) |
3.7 代码示例:Header 生成与编码
以下 Node.js 代码演示了如何生成 JWT Header 并进行 Base64URL 编码:
const crypto = require('crypto');
// 1. 构建 Header JSON
const header = {
typ: 'JWT',
alg: 'HS256'
};
// 2. 序列化为字符串
const headerStr = JSON.stringify(header);
// 3. Base64URL 编码
function base64urlEncode(str) {
return Buffer.from(str)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
const encodedHeader = base64urlEncode(headerStr);
console.log('Encoded Header:', encodedHeader);
// 输出: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
实战建议:在 SaaS 多租户架构中,建议使用 RS256 算法。每个租户可以拥有独立的密钥对,签发方持有私钥,各微服务通过共享的公钥验证令牌,无需在服务间传递敏感密钥。