JWT 解码工具

在线解码 JSON Web Token,查看头部、载荷与过期时间。完全在浏览器内运行,token 不会被传输或记录。

所有处理均在你的浏览器内完成,数据不会上传。

使用方法

  1. 把 JWT 粘贴进输入框,随输入实时解码;带 Bearer 前缀也能识别。
  2. 查看格式化后的头部与载荷。
  3. 看有效性徽章——它会用你的本机时钟换算 expnbf
  4. 签名原样展示,但不做验证,原因见下。

关于 JSON Web Token

JWT 是用点号连接的三段 base64url 编码内容:描述签名算法的头部、承载声明的载荷,以及对 前两段计算出的签名。因为这些段落只是编码,解码不需要密钥、也不需要服务端——这正是本工具 能完全在浏览器内离线工作的原因。

最容易让人栽跟头的性质是:JWT 并没有加密。Base64 是编码不是密码学变换,任何持有 token 的人都能读出其中每一项声明。签名保证的是签发后内容未被改动,仅此而已。载荷里放 用户 ID 或角色没问题;但 API 密钥、不该让用户看到的邮箱,或任何你不愿写进日志的东西, 都不该出现在那里。

几乎所有实现都会认的是那几个注册声明:exp(过期)、iat(签发时间)、nbf(生效 时间)、sub(主体)、iss(签发方)、aud(受众)。三个时间声明都是以秒为单位的 Unix 时间戳,这在 JavaScript 里是高频 bug 来源——那里的 Date 要的是毫秒。

最后关于「信任」:本工具告诉你的是 token 说了什么,而不是这个 token 是否为真。这是两个 不同的问题,只有持有密钥的服务端能回答第二个。一个能干净解码、也没有过期的 token, 完全可能是彻头彻尾伪造的。

常见问题

把真实的 token 粘贴到这里安全吗?

比大多数 JWT 工具安全,因为本工具没有服务端。token 由你标签页里的 JavaScript 解码,不会发送到任何地方——打开浏览器的网络面板即可确认。不过有个习惯值得一直保持:生产环境的 JWT 在过期前就是一份有效凭据,把它粘贴进任何网站都该是一个有意识的决定。

为什么这个工具不验证签名?

因为验证需要密钥,而向你索取密钥恰恰是危险的那一步。使用 HMAC 算法时,验证用的密钥和签发用的是同一个——交出去,对方就能以你的名义签发 token。解码则完全不需要密钥,所以本工具只做能安全完成的那部分,并把不做的那部分讲清楚。

JWT 是加密的吗?

不是,这一点经常让人意外。头部和载荷只是 base64url 编码,不是加密——任何拿到 token 的人都能读出里面的每一项声明。签名保证的是内容未被篡改,而不是内容不可见。永远不要把机密信息放进 JWT 的载荷。

alg: none 是什么意思?

它声明这个 token 没有签名。规范里保留这个取值,是为了完整性由其他手段保证的场景,但它后来成了一个著名漏洞:有些库直接采信头部里的算法字段,于是攻击者把签名删掉、把 alg 改成 none,就能让库接受伪造的 token。正确的实现会固定预期算法,而不是从 token 里读。

为什么 exp 是一个数字而不是日期?

按 RFC 7519,它是以秒为单位的 Unix 时间戳。在 JavaScript 里处理它最常见的错误是忘了 Date 接受的是毫秒——new Date(exp) 会得到 1970 年的某一天,new Date(exp * 1000) 才是你想要的。本工具同时显示原始数字与换算后的本地时间,方便对照。

token 能解码,但网站说它无效,为什么?

解码只能证明格式正确。服务端拒绝它的原因可能是本工具看不到的:签名不对、issuer 或 audience 不匹配、会话已被吊销,或者两台机器时钟不同步。只有「过期」是仅凭 token 本身就能看出来的,所以这里专门标了出来。