使用方法
- 粘贴完整的令牌,即用点号分隔的三段 Base64URL。
- 查看解码后的头部和载荷。exp、iat 和 nbf 会显示为日期,令牌已过期或尚未生效时会给出提示。
- 如需验证签名,HS256、HS384、HS512 请输入共享密钥,RS、PS、ES 系列算法请粘贴 PEM 格式的公钥。
- 确认签发者、受众和主题等声明与你的应用预期一致。
JWT 的结构
JSON Web Token(RFC 7519)由点号分隔的三部分组成:header.payload.signature。头部和载荷都是 JSON 对象,经过不带填充的 Base64URL 编码,所以令牌几乎总是以 eyJ 开头,这正是开头的 {" 编码后的样子。签名则是对前两部分(按令牌中的原样)计算得出的。
- 头部:在
alg中指明签名算法,通常带有"typ": "JWT",并常用kid标明所用的密钥。 - 载荷:即各项声明,例如用户是谁、令牌由谁签发、何时过期。
- 签名:HMAC、RSA 或 ECDSA 签名,用来证明头部和载荷未被篡改。
如果令牌由五部分组成,那就是加密的 JWE,没有解密密钥无法读取其内容。
注册声明
| 声明 | 名称 | 含义 |
|---|---|---|
iss | 签发者 | 创建并签名该令牌的一方 |
sub | 主题 | 令牌所代表的对象,通常是用户 ID |
aud | 受众 | 令牌的目标服务 |
exp | 过期时间 | 超过该时间后必须拒绝该令牌 |
nbf | 生效时间 | 早于该时间时必须拒绝该令牌 |
iat | 签发时间 | 令牌的创建时间 |
jti | JWT ID | 唯一标识,用于防止重放 |
时间采用 NumericDate 格式,即自 1970 年 1 月 1 日 UTC 起的秒数,而不是毫秒数。解码工具会把它们显示为易读的日期,并与你设备上的时钟进行比较。
解码不等于验证
任何人都能解码 JWT,因为载荷只是经过编码,并没有加密,所以绝不要在其中存放密码或其他机密信息。令牌是否可信,只能通过用正确的密钥验证签名来确认。接收令牌的服务器还应当:
- 只允许预期的算法,并拒绝
"alg": "none",它表示令牌没有签名; - 绝不能让令牌头部决定使用 HMAC 还是 RSA,否则攻击者可以把你的公钥当作 HMAC 密钥来伪造令牌;
- 每次请求都检查
exp、nbf、iss和aud。
本页的签名验证功能使用浏览器内置的 Web Crypto API,解码和验证都在你的设备上完成,不会上传任何内容。但作为通用原则,切勿把生产环境的签名密钥或仍然有效的令牌粘贴到你不信任的网站上。
常见问题
把 JWT 粘贴到这里安全吗?
令牌由浏览器中的 JavaScript 解码和验证,不会发送到任何服务器。但请记住,未过期的令牌对持有者来说就相当于密码,分享截图或日志时最好使用测试令牌或已过期的令牌。
没有密钥也能解码 JWT 吗?
可以。头部和载荷只是经过 Base64URL 编码的 JSON,不需要任何密钥就能读取。只有验证签名时才需要密钥或公钥。
为什么提示我的令牌已过期?
exp 声明早于你设备上的当前时间。如果令牌本应仍然有效,请检查系统时钟以及签发方设置的令牌有效期。支持验证哪些签名算法?
使用共享密钥的 HS256、HS384、HS512,以及使用 PEM 格式公钥的 RS256、RS384、RS512、PS256、PS384、PS512、ES256、ES384 和 ES512。
"alg": "none" 是什么意思?
它表示令牌未经保护、签名为空,由 RFC 7518 定义。任何人都可以创建或修改这样的令牌,因此要求签名令牌的服务器必须始终拒绝它。