- 2021/09/20, jwt.io 上的 "secret base64 encoded"
- 2021/12/25, Nginx JWT 认证
- 2022/03/09, Golang JWT
- 2022/03/28, 和 JWT 关系密切的一些规范
JWT 介绍
一句话介绍 JWT:就是通过非对称加密算法签名的方式,将部分用户信息存在客户端。
全名 JSON Web Token,简称 JWT。
内容 = 头 Headers (JSON) + 负载 Payload (JSON) + 签名 Signature
分别 Base64 编码之后,用 . 连接。

JSON 实现
import base64
def jsonify(obj):
return json.dumps(obj, ensure_ascii=False, separators=',:')
def base64urlEncoding(s):
return base64.urlsafe_b64encode(s).rstrip(b'=').decode('ascii')
def sign(key, msg):
return base64urlEncoding(hmac.new(key, msg, hashlib.sha256).digest())
# def verify(key, msg, sig):
# return key.verify(msg, base64.urlsafe_b64decode(sig))
def e(obj):
return base64urlEncoding(jsonify(header).encode('utf-8'))
def encode(key, header, payload):
s = e(header) + '.' + e(payload)
return s + '.' + sign(key, s)
def decode(token):
header_str, payload_str, sig = token.split('.')
header = json.loads(base64.urlsafe_b64decode(header_str).decode('utf-8'))
payload = json.loads(base64.urlsafe_b64decode(payload_str).decode('utf-8'))
sig = base64.urlsafe_b64decode(sig)
header = {
"alg": "HS256",
"typ": "JWT"
}
payload = {
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
signature = HMAC_SHA256(
secret,
base64urlEncoding(header) + '.' +
base64urlEncoding(payload)
)
const token = base64urlEncoding(header) + '.' + base64urlEncoding(payload) + '.' + base64urlEncoding(signature)
标准字段
Header 字段
| Code | Name | Description |
|---|---|---|
typ |
Type | Token 类型,通常为 JWT,用于声明整个对象的类型。 |
cty |
Content Type | 内容类型,用于声明 Payload 中嵌套对象的类型;嵌套 JWT 时常使用 JWT。 |
alg |
Algorithm | 签名或加密所使用的算法,例如 HS256、RS256、ES256。 |
kid |
Key ID | 密钥标识,用于帮助接收方选择对应的验证密钥。 |
x5c |
X.509 Certificate Chain | X.509 证书链,以 Base64 编码的 DER 证书数组表示。 |
x5u |
X.509 URL | 指向 X.509 公钥证书或证书链的 URL。 |
x5t |
X.509 SHA-1 Thumbprint | X.509 证书的 SHA-1 指纹。 |
x5t#S256 |
X.509 SHA-256 Thumbprint | X.509 证书的 SHA-256 指纹。 |
jku |
JWK Set URL | 指向 JSON Web Key Set(JWKS)的 URL,用于获取验证所需的公钥。 |
jwk |
JSON Web Key | 直接在 Header 中携带用于验证签名的 JSON Web Key。 |
Claim 字段(Payload 字段)
| Code | Name | Description |
|---|---|---|
iss |
Issuer | Token 的签发者。 |
sub |
Subject | Token 所代表的主体,通常用于表示用户或资源的唯一标识。 |
aud |
Audience | Token 的受众,即允许使用该 Token 的服务或服务集合。 |
exp |
Expiration Time | Token 的过期时间,使用 Unix 时间戳。 |
nbf |
Not Before | Token 开始生效的时间,使用 Unix 时间戳。 |
iat |
Issued At | Token 的签发时间,使用 Unix 时间戳。 |
jti |
JWT ID | JWT 的唯一标识,可用于防重放、Token 撤销和审计追踪。 |
关于 JWT 的看法
-
相比传统 Session,JWT 可以减少认证状态存储带来的 DB/Redis 查询。
- Session 通常需要服务端维护 Session 状态,请求到达后需要查询 Session Store。
- JWT 将部分认证信息放在 Token 中,服务端验证签名即可完成认证,不需要每次查询 Session Store。
- 但 JWT 并不意味着完全不需要 DB/Redis。业务数据、权限数据、Token 撤销状态等仍然可能需要查询。
-
JWT 的主要优势是无状态认证,但“注销 / 踢下线”会重新引入状态。
- JWT 一旦签发,在
exp到期之前通常都有效。 -
如果需要立即注销某个 Token,可以维护黑名单,例如:
revoked_jti → expiration_time -
网关或认证服务可以定期同步黑名单,也可以通过 Redis 等共享存储实时查询。
- 如果对“立即注销”的一致性要求不高,可以接受一定同步延迟。
- 如果认证系统发生故障,可以根据业务要求选择继续验证 JWT或拒绝认证,但不能简单地认为“去掉黑名单检查就是降级”;这实际上是安全策略的改变。
- JWT 一旦签发,在
-
相比加密 Cookie,JWT 不依赖 HTTP Cookie,适用场景更加广泛。
- Cookie 是 HTTP 状态管理机制,浏览器会自动携带。
-
JWT 本质上只是一个 Token,可以放在:
Authorization: Bearer <token>- Cookie
- WebSocket 握手
- 移动端请求
- 服务间调用
-
因此 JWT 与 Cookie 实际上不是完全互斥的概念:JWT 也可以放在 Cookie 中。
-
JWT 应尽可能保持短小。
- JWT 会随着请求发送,因此 Payload 越大,请求开销越大。
-
通常只需要保存少量认证相关信息,例如:
{ "sub": "123456", "iss": "auth.example.com", "iat": 1780000000, "exp": 1780003600 } -
不建议把用户资料、权限列表、大量业务数据直接塞进 JWT。
- JWT 更适合表达“这个 Token 是谁签发的、代表谁、给谁使用、什么时候有效”,而不是作为一个用户数据容器。
- 如果需要携带大量信息,应考虑通过
sub等标识再查询业务数据。
-
JWT 很适合在 API Gateway / BFF 层统一完成认证校验。
-
网关可以统一完成:
- Token 格式检查
- 签名验证
exp/nbf校验iss/aud校验- 黑名单检查
-
校验通过后,可以将用户身份信息传递给后端服务,例如:
X-User-ID: 123456 X-User-Roles: admin -
这样业务服务无需重复实现 JWT 验证逻辑。
- 但认证和授权不是一回事。网关完成身份认证后,具体业务服务仍然应该根据业务资源执行授权判断。
-
-
JWT 对跨域 API 场景比较友好,但它本身并没有“解决跨域”。
- 跨域主要由浏览器的 CORS 机制决定。
-
如果使用:
Authorization: Bearer <JWT>前端可以主动携带 Token,并通过服务端 CORS 配置允许
Authorization请求头。 -
相比依赖 Cookie 的认证方式,Bearer Token 不需要依赖浏览器的 Cookie 自动携带机制,因此在前后端分离、移动端、第三方 API 等场景下通常更加灵活。
- 如果 JWT 放在 Cookie 中,那么仍然需要处理
SameSite、Secure、HttpOnly、CORS 等 Cookie 相关问题。
-
JWT 最大的价值不是“比 Session 更高级”,而是把认证状态的一部分从服务端 Session Store 转移到了客户端 Token,从而实现无状态认证。
代价也很明确:
方案 服务端状态 服务端注销 请求大小 横向扩展 Session 有 简单 小 依赖共享 Session JWT 无 不支持 较大 简单 JWT + 黑名单 少量 简单 较大 需要共享黑名单 传统单体 Web 应用使用 Session 更简单,多服务、API、网关认证等场景适合 JWT。