跳到主要内容

JWT 批量解码实战:一堆令牌批量看 claims 不验签

把一整批 JWT 粘进来,批量解码看载荷里的 exp 过期时间和 sub 用户 ID,不验签只读 claims。审计令牌、排查批量鉴权问题,全程浏览器本地处理,令牌不上传服务器。

发布于 作者 李雷
#JWT #令牌审计 #鉴权排查 #本地工具

JWT 批量解码:把一堆令牌的载荷一次看清

排查鉴权问题时,我手里常常是一整列 JWT,几十上百个,从客服工单、日志、CSV 导出里东拼西凑出来的。一个个粘到在线解码器里看,既慢又危险,因为很多在线工具会把令牌发到它们自己的服务器。我要的是把这一批令牌批量解码,只看载荷里的 claims,不需要验签,而且全程别离开我的浏览器。

JWT 的结构:为什么不验签也能读懂载荷

一个 JWT 由三段组成,用点号分隔:header.payload.signature。前两段都是 Base64URL 编码的 JSON。把中间那段(payload)做 Base64URL 解码,你就直接拿到一个 JSON 对象,里面是这枚令牌承载的所有声明(claims)。

注意 Base64URL 不是标准 Base64,它把 + 换成 -/ 换成 _,而且通常省略末尾的 = 填充。所以解码前要先补回填充、还原字符,再做标准 Base64 解码。这一步纯粹是字符串和字节运算,不需要任何密钥,也就不需要联网。验签是另一回事,验签要拿到签发方的密钥,而读载荷只是解码,两者完全分开。

批量解码能拿到哪些 claims

把一批令牌批量解码后,你最常盯的是这几个标准声明:

  • exp:过期时间,Unix 时间戳。排查"为什么一批用户突然全掉线",先看这一列。
  • iat:签发时间,配合 exp 能算出令牌的有效时长。
  • sub:主体,通常就是用户 ID。批量对照哪些用户的令牌出了问题,靠它。
  • iss / aud:签发方和接收方,排查跨服务调用串号时很有用。

一个真实的输入输出例子

假设我从日志里抓到这样一枚令牌(中间段是 Base64URL):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEwMjQiLCJpYXQiOjE3MTgyNDU2MDAsImV4cCI6MTcxODI0OTIwMH0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

把中间段单独拎出来做 Base64URL 解码,得到的 JSON 载荷是:

{
  "sub": "user_1024",
  "iat": 1718245600,
  "exp": 1718249200
}

读出来就清楚了:这枚令牌属于用户 user_1024,签发时间 1718245600(2024-06-13 02:26 UTC),过期时间 1718249200,中间正好相差 3600 秒,也就是有效期一小时。当一整批令牌排开,我能立刻看出哪些 exp 已经过去、哪些 sub 重复签发、哪些 iat 异常地早,鉴权问题的线索就在这一眼里。

审计令牌和排查批量鉴权问题

我自己最常用的场景是这样:线上报"部分用户 401",我把网关日志里所有 Authorization 头里的 Bearer 令牌导出来,粘进转换器,批量解码,按 exp 排序。三分钟之内就能判断是不是一批令牌集体到期、是不是某个签发服务时钟漂了、是不是 aud 配错了指向。比起一个个手点解码,这是数量级的差距。解出来的列表还能直接导成 CSV 或 JSON 留作审计线索,而不是只截个图。

需要注意一点:格式正确不等于令牌真实有效。能解出干净的 claims 只说明它是个结构合法的 JWT,账号是否还存在、签名是否被改过,这些读载荷是看不出来的。审计时把"解码读到的内容"和"服务端验签的结果"分开记,才不会误判。

为什么坚持本地处理

JWT 即使不验签,载荷里也常带着 sub 这样的用户标识,甚至业务自定义的敏感字段。把这些发到第三方服务器去解码,等于把内部身份信息泄给了别人。JWT Token 列表转换器 的解码、去重、排序、导出全部在当前标签页用浏览器完成,令牌不会发到 Toolora 的服务器,这也是我敢拿真实线上令牌往里粘的前提。

如果你的输入更杂,比如令牌混在大段 HTML 或 Markdown 里,可以先用 JWT Token 提取器 把令牌从噪音里抓出来,再做批量解码。整条链路都在本地,从抓取到解码到导出,敏感令牌一步都不出浏览器。

把一堆 JWT 摊开看清它们的 claims,本该是审计和排障里最基础的一步。让它快、让它批量、让它留在本地,排查鉴权问题才不会被工具拖后腿。


Made by Toolora · Updated 2026-06-13