怎么用
- 粘贴 token。从 Authorization 请求头里复制来的「Bearer 」前缀会被自动去掉。
- 头部和载荷会以格式化的 JSON 显示。标准声明带有中文说明,时间类声明(exp、nbf、iat)同时显示原始数字和对应的 UTC 日期。
- 状态栏会说明 token 是已过期、尚未生效,还是根本没有设置过期时间。
- 遇到有风险的 token,比如算法为 "none" 的,会给出警告。
JWT 里装的是什么
JSON Web Token(RFC 7519)由三段 Base64url 编码的内容用点号连接而成。头部是一个很小的 JSON 对象,写明签名算法(alg),通常还有类型(typ)。载荷是一个由声明组成的 JSON 对象,记录用户或会话的信息。签名是用密钥或私钥对前两段计算出来的。
解码只是做 Base64url 解码和 JSON 解析,不涉及任何密钥。这就是本工具能做到的原因,也意味着任何拿到 token 的人都能看到里面的内容。绝不要把密码这类秘密放进 JWT 的载荷。
标准声明
| 声明 | 含义 |
|---|---|
| iss | 签发者 |
| sub | 这个 token 描述的对象,通常是用户 ID |
| aud | 这个 token 给谁用 |
| exp | 过期时间,自 1970 年起的秒数(NumericDate) |
| nbf | 在这个时间之前不得接受 |
| iat | 签发时间 |
| jti | 唯一编号,用于防止重放 |
为什么解码不等于验证
校验一个 token,要用签发方的密钥重新计算签名并比对,再检查 exp、nbf、iss、aud 是否符合应用的预期。一个解码工具显示出看似正常的载荷,什么也证明不了,因为任何人都能构造出任意内容的 token。服务器还必须拒绝 "alg": "none",并且不能让 token 自己的头部来决定用哪种算法验签,这两点都是 JWT 最佳实践 RFC 8725 里描述过的常见攻击手法。
示例
RFC 7519 第 3.1 节给出了这个示例 token(为了显示加了换行):
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.
dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk它的头部解码为 {"typ":"JWT","alg":"HS256"},载荷解码为 {"iss":"joe","exp":1300819380,"http://example.com/is_root":true}。exp 的值 1300819380 对应 UTC 2011 年 3 月 22 日 18:43:00(北京时间 3 月 23 日 02:43:00),所以工具会显示已过期。自定义声明 http://example.com/is_root 说明声明名可以用 URI,以避免重名。
不是 token 的输入会得到具体的提示:「abc.def」只有两段;第一段含有 Base64url 字母表以外的字符,会在头部报错;载荷解码出来是普通文字而不是 JSON 对象,会在载荷报错。
局限
- 不校验签名,原因见上文。请在服务端用 JWT 库完成校验。
- 加密的 token(JWE)有五段,载荷是加密的,没有密钥读不出来,本工具会提示段数不对。
- 时钟偏差。 是否过期按你设备的时钟判断。服务器通常允许一两分钟的误差,所以这里显示刚过期的 token,服务器可能仍然接受。
常见问题
把真实的 token 粘贴到这里安全吗?
token 在你的浏览器里解码,不会通过网络发送。尽管如此,仍应把线上 token 当作密码对待:用完清空输入框,能用过期或测试 token 时尽量用它们。
能校验签名吗?
不能。校验需要签发方的密钥或公钥。本页只负责把 token 解码成可读的内容。
exp 的数字怎么看?
它是自 1970 年 1 月 1 日 UTC 起的秒数。工具会在原始数字旁边显示对应的日期。
"alg": "none" 是什么意思?
表示这个 token 没有签名,绝不能被当作身份凭证接受。
为什么任何人都能看懂我的 JWT?
因为头部和载荷只是做了 Base64url 编码,没有加密。签名的作用是防止被篡改,而不是防止被读取。