如何使用 JWT 解码器
- 粘贴一个 JSON Web Token,也就是通常跟在
Authorization: Bearer后面的那串长字符串。 - 头部和载荷会被解码,并以格式化的 JSON 显示。
exp、iat和nbf等时间声明会被转换为易读的日期,让您一眼就能看出令牌是否已过期。
JWT 的结构
JSON Web Token 由 RFC 7519 定义,是一种在各方之间传递声明的紧凑格式。常见的签名形式(JWS)由三部分组成,以点号分隔:
header.payload.signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMifQ.<signature>
- 头部(Header):描述令牌的 JSON,主要是签名算法。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9解码后为{"alg":"HS256","typ":"JWT"}。 - 载荷(Payload):包含各项声明的 JSON,即关于用户或会话的陈述。
- 签名(Signature):使用密钥(HMAC,例如 HS256)或私钥(例如 RS256、ES256)对编码后的头部和载荷计算得出。
每一部分都采用 base64url 编码,即不带填充、对 URL 安全的 Base64 字符集。这就是令牌中会出现 - 和 _ 的原因,也是 JWT 几乎总以 eyJ 开头的原因:当 JSON 对象开头的 {" 后面跟着一个常见的小写键名时,编码结果就是这样。您可以用 Base64 编码与解码工具亲自探索这种编码。
注册声明
| 声明 | 名称 | 含义 |
|---|---|---|
iss | 签发者 | 创建并签署令牌的一方。 |
sub | 主题 | 令牌所涉及的对象,通常是用户 ID。 |
aud | 受众 | 令牌的目标服务(一个或多个)。 |
exp | 过期时间 | Unix 时间戳,在此之后令牌必须被拒绝。 |
nbf | 生效时间 | Unix 时间戳,在此之前令牌尚未生效。 |
iat | 签发时间 | 令牌创建时的 Unix 时间戳。 |
jti | JWT ID | 唯一标识符,可用于防止重放攻击。 |
在 RFC 7519 中,这些声明都是可选的;由应用程序决定需要哪些。时间声明的单位是秒,而不是毫秒;Unix时间戳转换器解释了两者的区别。
常见误区
解码不等于验证
任何人都可以解码 JWT,本工具做的正是这件事。解码只能告诉您令牌声称了什么,而不能说明这些声明是否真实。服务器在信任载荷中的任何内容之前,必须使用正确的密钥验证签名,并检查 exp、nbf、iss 和 aud。
载荷并不保密
任何持有签名 JWT 的人都可以读取其内容。不要在载荷中放入密码、不应向客户端暴露的个人数据或内部机密。如果内容必须保密,请使用加密 JWT(JWE),或把数据保存在服务器端。
alg: none 与算法混淆
JOSE 规范为签名为空的无保护令牌定义了 "alg": "none" 值。如果某个库照单全收令牌自身的头部,就可能接受下面这样的伪造令牌:
{"alg": "none", "typ": "JWT"}
{"sub": "admin"}
(空签名)
另一种相关攻击会把 RS256 令牌改成 HS256,从而把公钥误当作 HMAC 密钥使用。两者的防御方法相同:在服务器上配置允许的算法,绝不让令牌自己选择。
使用建议
- 让访问令牌保持较短的有效期,较长的会话则使用刷新令牌。
- 在多台服务器之间检查
exp和nbf时,允许少量的时钟偏差(例如一分钟)。 - 使用维护良好的 JWT 库,而不是手动解析和验证令牌。
常见问题
这个工具能验证 JWT 签名吗?
验证需要签发者的密钥或公钥,并且必须在您的后端完成。本工具用于在调试时查看令牌的头部和声明。
为什么我的令牌显示已过期?
exp 声明早于您设备上的当前时间。请检查您的时钟是否准确,以及签发者写入的 exp 是否以秒为单位。
JWT 是加密的吗?
绝大多数使用中的签名 JWT(JWS)只是经过编码和签名,因此任何人都能读取。加密 JWT(JWE)由五部分组成,而不是三部分。
把令牌粘贴到这里安全吗?
解码在本地进行,不会传输任何内容。一般来说,不要把正在使用的生产环境令牌粘贴到任何您没有审查过的在线工具中。
更新于