JWT 解码器
在浏览器中解码 JWT(JSON Web Token),可视化 header、payload 和 signature。iat / exp / nbf 会自动转换为可读日期。
Header
Payload
Signature
* 签名验证需要密钥或公钥,本工具仅进行解码。
关于 JWT 的结构
JWT 是由 header.payload.signature 三部分用点(.)连接的字符串。header 和 payload 是 Base64URL 编码的 JSON,signature 由 header 中指定的算法(HS256 / RS256 等)生成。
主要 claim: iss(发行者)、sub(主题)、aud(接收者)、exp(有效期)、nbf(生效时间)、iat(签发时间)、jti(JWT ID)
📖 常见的坑
把 JWT 拆分为头部、载荷与签名并展示,并将 exp、iat 这类时间声明转换为可读日期。处理全部在浏览器内完成,不做签名验证(那需要密钥)。要记住的关键是:「能解码」就意味着「任何人都能读到里面的内容」——JWT 的载荷并未加密,只是做了 Base64URL 编码。
| 情形 | 会发生什么 | 怎么处理 |
|---|---|---|
| 把机密塞进载荷里 | Base64URL 是编码而非加密——正如本页所展示的,任何没有密钥的人都能读到内容。可「有签名所以安全」这个误解却顽固得很,于是能看到这样的设计:把个人信息、内部权限结构、公司内部 ID,有时还有邮箱和出生日期,统统塞进载荷。JWT 会存在 localStorage 或 Cookie 里、会出现在日志中,有时还会出现在 URL 上——把它的内容当作公开信息来对待,才是准确的态度。 |
载荷里只放「标识符」,其余的到服务端去查——放用户 ID 与角色名即可,不要放姓名、邮箱、住址。若确实需要加密,另有 JWE(JSON Web Encryption)这一规范,但在此之前请先反问「它是否有必要放进 JWT」:多数情况下你需要的只是「这是谁」,至于「他是什么」,服务端知道就够了。判断标准很简单:这个值以明文出现在访问日志里,你介意吗?不介意就可以放;介意就不能放。 |
| 只解码就信了里面的内容 | 不验证签名,JWT 就只是一串用户可以随意改写的文本。解码后读到 role: "admin" 并据此做权限判断的代码,会原样接受攻击者自己写上这个值的令牌。历史上有两个著名的失败案例。其一是 alg: "none" 攻击:把头部的算法改成 none、签名留空,某些实现就照单全收。其二是 HS256 与 RS256 的混淆:诱使验证方把公钥当作 HMAC 的共享密钥,攻击者仅凭公开信息就能伪造出有效签名。 |
验证请务必使用库提供的验证函数,并显式固定允许的算法——写成 jwt.verify(token, key, { algorithms: ["RS256"] })。省略这个参数,某些实现就会信任头部的 alg——那等于让攻击者可控的值来决定「如何验证」。绝不要把「只解码」的函数(名字类似 jwt.decode 的那种)用于授权判断:名字太像容易混淆,但它根本不做验证,只用于调试输出。动手写代码前,请务必确认你所用库里哪个函数验证、哪个只是解码。 |
| 已经登出了,令牌却还能用 | 无状态既是 JWT 的设计优势,也是它最大的约束。服务端并不保存令牌,因此签发之后就没有办法单独作废某一个。所谓登出,实际上只是「在客户端把令牌丢掉」,而复制过它的人,在过期之前都可以继续使用。同理,即便撤销了权限,已签发的令牌里写的仍是旧权限。「明明已经切断了离职人员的访问,却还能用一个小时」,就是这么回事。 | 请缩短有效期,并与刷新令牌配合使用——访问令牌设为 15 分钟左右,续期使用由服务端管理的刷新令牌。这样一来,作废刷新令牌后最多 15 分钟权限就会断掉。若「立即失效」是硬性要求,就需要黑名单——保存被作废令牌的 ID,并在验证时比对——但这意味着要持有状态,也就放弃了使用 JWT 的部分理由。分岔点正在于此:如果确实需要立即失效,老老实实用会话 ID 加服务端会话,更简单也更可靠。JWT 适合的是跨多个服务的认证,或者你希望把验证本身分散开的场合。 |
时间声明的单位是秒。exp、iat、nbf 都是 Unix 秒,填入毫秒会让有效期落到五万年之后——实际上就是一个永不过期的令牌。由于 JavaScript 的 Date.now() 返回毫秒,写成 Date.now() + 3600000 直接塞进 exp 是非常常见的错误;正确写法是 Math.floor(Date.now() / 1000) + 3600。如果解码出的日期落在遥远的未来,请正是怀疑这一点——本页把时间声明转成可读日期,正是为了让你用眼睛抓住它。其次,验证 nbf 与 exp 时请留出数十秒的宽限(leeway),以吸收服务器之间的时钟偏差;主流库都有这个选项。最后是运维上的提醒:不要把仍在有效期内的生产令牌粘贴到在线 JWT 解码器——它就是凭据本身,一旦进了你粘贴目标那台服务器的日志,别人就能拿它冒充你。本页完全在浏览器内运行,但请养成在开发者工具的 Network 面板中确认这一点的习惯。
📖 使用方法
-
1
复制 JWT从 API 响应或 Authorization 头获取 JWT 字符串。
-
2
粘贴到输入框将 JWT 粘贴到顶部文本区,自动解码。
-
3
查看 header 和 payload查看算法(alg)、发行者(iss)、过期时间(exp)等 claim。
❓ 常见问题
什么是 JWT?
可以验证签名吗?
输入的 JWT 会发送到服务器吗?
exp 已过期怎么办?
🐛 此工具出现问题了吗?
免费、无需注册。仅提供复现步骤也有帮助。报告将直接发送给运营者并用于改进。
感谢您的反馈!
已送达运营者,将用于改进工具。