JWT 是什么?手把手教你在线解析 Token,还支持离线桌面版

做后端开发、接口联调或者登录鉴权时,我们经常会遇到一长串这样的内容:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMDAwMSIsIm5hbWUiOiJKYXZhUHViIn0
.xxxxxxxxxxxxxxxxx

它看起来像一段乱码,实际上大概率是一个 JWT。

在开发过程中,我们经常需要查看 JWT 中保存了哪些信息:

  • 当前登录的是哪个用户?
  • Token 是什么时候签发的?
  • Token 有没有过期?
  • 用户拥有哪些角色和权限?
  • Token 是由哪个系统签发的?
  • 为什么前端带了 Token,后端仍然返回 401?

每次手动拆分、解码比较麻烦,所以我做了一个简单的 JWT 在线解析工具。

它可以直接解析 JWT 的 Header、Payload、Signature,并把过期时间、签发时间、生效时间等字段转换成容易阅读的格式。

除了在线使用,这套工具还提供 Windows 离线桌面版。对于不方便把 Token 粘贴到在线网站中的场景,可以直接断网使用。


在这里插入图片描述

一、JWT 是什么?

JWT 的全称是:

JSON Web Token

它是一种用于在不同系统之间安全传递信息的开放标准。

JWT 经常被用于:

  • 用户登录状态
  • 接口身份认证
  • 单点登录
  • 前后端分离项目
  • 微服务身份传递
  • API 访问授权
  • 临时下载凭证

最常见的使用方式,就是用户登录成功后,服务器生成一个 JWT 返回给前端。

前端以后请求接口时,把 JWT 放到 HTTP 请求头中:

Authorization: Bearer <你的JWT>

服务器收到请求后,会检查这个 JWT 是否有效,再决定是否允许用户访问接口。


二、JWT 由哪几部分组成?

一个常见的 JWT 由三部分组成,中间使用英文句号分隔:

Header.Payload.Signature

也就是:

头部.载荷.签名

例如:

xxxxx.yyyyy.zzzzz

这三部分分别承担不同的作用。

1. Header:头部

Header 一般用来描述 Token 类型和签名算法。

例如:

{
  "alg": "HS256",
  "typ": "JWT"
}

其中:

  • alg 表示签名算法;
  • typ 表示 Token 类型。

这里的 HS256 表示该 JWT 使用 HMAC SHA-256 算法生成签名。

实际项目中还可能看到:

RS256
ES256
HS384
HS512

不同算法使用的密钥和验证方式并不相同。


2. Payload:载荷

Payload 是 JWT 中真正承载业务数据的部分。

例如:

{
  "sub": "10001",
  "name": "JavaPub",
  "roles": [
    "developer",
    "admin"
  ],
  "iat": 1785456000,
  "exp": 1785459600
}

项目通常会在 Payload 中保存:

  • 用户 ID
  • 用户名
  • 用户角色
  • 权限列表
  • Token 签发时间
  • Token 过期时间
  • 签发系统
  • 目标服务

需要注意:

JWT 的 Payload 只是经过 Base64URL 编码,并没有被加密。

只要拿到 JWT,通常就可以解析出 Payload 中的内容。

所以不要在 JWT 中保存以下信息:

  • 用户密码
  • 支付密码
  • 私钥
  • API Key
  • 身份证号码
  • 银行卡信息
  • 其他高度敏感的数据

JWT 可以防止内容被随意篡改,但默认不能防止别人读取其中的内容。


3. Signature:签名

Signature 用于验证 JWT 是否被修改。

以 HS256 为例,签名的生成逻辑可以简化理解为:

HMACSHA256(
  Base64Url(Header) + "." + Base64Url(Payload),
  Secret
)

服务器会使用自己的密钥重新计算签名。

如果计算结果与 JWT 中携带的 Signature 一致,说明 Header 和 Payload 在传输过程中没有被修改。

如果有人把:

{
  "role": "user"
}

改成:

{
  "role": "admin"
}

但不知道服务器的密钥,就无法生成正确的签名。

服务器进行签名校验时,便会发现这个 Token 已经被篡改。


在这里插入图片描述

三、JWT 可以直接解析,是不是不安全?

这是很多初学者第一次接触 JWT 时都会产生的疑问。

既然 Payload 可以直接解析出来,JWT 还有什么安全性?

这里需要分清两个概念:

编码不等于加密

JWT 的 Header 和 Payload 通常只是进行了 Base64URL 编码,所以能够被任何拿到 Token 的人读取。

JWT 的核心安全能力不是隐藏内容,而是:

防止内容被伪造和篡改

服务器通过 Signature 判断 JWT 是否由可信系统签发,以及中间有没有被修改。

因此:

  • 能解析 JWT,不代表能够伪造 JWT;
  • 能修改 Payload,不代表修改后的 JWT 可以通过服务器验证;
  • JWT 中不应该保存不能被别人看到的敏感信息;
  • 服务端不能只解析 Payload,必须验证签名。

四、JWT 中常见字段是什么意思?

JWT Payload 中有一些比较常见的标准字段。

iss:签发方

iss 是 Issuer 的缩写,表示 JWT 由谁签发。

例如:

{
  "iss": "api.example.com"
}

在微服务或单点登录系统中,服务端可以通过 iss 判断 Token 是否来自可信的认证服务。


sub:主题

sub 是 Subject 的缩写,通常用于表示当前 Token 对应的用户或主体。

例如:

{
  "sub": "10001"
}

这里的 10001 可能就是用户 ID。


aud:受众

aud 是 Audience 的缩写,表示这个 Token 是提供给哪个系统或服务使用的。

例如:

{
  "aud": "order-service"
}

如果一个签发给订单服务的 Token 被拿去访问管理系统,管理系统可以通过校验 aud 拒绝这次请求。


iat:签发时间

iat 是 Issued At 的缩写,表示 JWT 的签发时间。

例如:

{
  "iat": 1785456000
}

这个数字通常是 Unix 时间戳,需要转换成正常日期才能方便阅读。


exp:过期时间

exp 是 Expiration Time 的缩写,表示 JWT 在什么时间过期。

例如:

{
  "exp": 1785459600
}

如果当前时间已经超过 exp,服务端通常会拒绝这个 Token,并返回:

401 Unauthorized

nbf:生效时间

nbf 是 Not Before 的缩写,表示 JWT 在指定时间之前不能使用。

例如:

{
  "nbf": 1785456000
}

即使签名正确,只要当前时间还没有到达 nbf,服务器也应该拒绝该 Token。


五、JWT 在线解析工具

为了方便开发和接口调试,我在 JavaPub Tools 中加入了一个 JWT 解析工具。

在线工具:

打开 JavaPub JWT 解析工具

项目源码:

查看 GitHub 开源仓库

工具目前支持:

  • 解析 JWT Header
  • 解析 JWT Payload
  • 展示 Signature 片段
  • 自动识别 Token 是否过期
  • 转换 exp 过期时间
  • 转换 iat 签发时间
  • 转换 nbf 生效时间
  • 展示 iss、sub、aud 等常见字段
  • 一键复制 Payload
  • 提供示例 JWT
  • 输入错误时给出格式提示

整个操作非常简单。


六、如何使用 JWT 解析工具?

第一步:复制 JWT

从接口请求、浏览器存储或者程序日志中复制需要检查的 JWT。

一个正常的 JWT 应该由三个部分组成:

Header.Payload.Signature

中间有两个英文句号。


第二步:粘贴到输入框

打开 JWT 解析工具,将完整 Token 粘贴到左侧输入框。

注意不要把下面的前缀一起复制进去:

Bearer

例如请求头原本是:

Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.xxxxx.xxxxx

实际需要粘贴的是:

eyJhbGciOiJIUzI1NiJ9.xxxxx.xxxxx

第三步:点击“解析 JWT”

点击解析按钮后,工具会自动将结果拆成四个区域:

Header
Payload
Token 状态
Signature

Header 区域可以查看 Token 类型和签名算法。

Payload 区域可以查看用户 ID、角色、权限以及其他业务字段。

Token 状态区域会自动展示:

  • Token 是否过期
  • 签发时间
  • 过期时间
  • 是否已经生效
  • 签发方
  • 主题
  • 受众

Signature 区域则会展示 JWT 的第三段签名内容。


七、一个实际的 JWT 排错案例

假设前端请求接口时收到:

401 Unauthorized

但开发人员确认请求头中已经携带了 Token。

这时可以先用 JWT 工具解析 Token。

假设解析结果如下:

{
  "sub": "10001",
  "name": "JavaPub",
  "iat": 1785456000,
  "exp": 1785459600
}

工具显示:

是否过期:已过期

那么这次 401 很可能不是请求头写错,而是 Token 已经过期。

前端需要重新登录,或者使用 Refresh Token 获取新的 Access Token。

再比如,Payload 中显示:

{
  "roles": [
    "user"
  ]
}

但这个接口只允许管理员访问。

那么即使 JWT 没有过期、签名也正确,服务器仍然可能返回:

403 Forbidden

通过解析 Payload,可以快速判断问题究竟出在:

  • Token 过期
  • 用户身份不对
  • 权限不足
  • 签发方不匹配
  • 受众不匹配
  • Token 尚未生效

八、为什么还要提供离线桌面版?

虽然在线工具使用方便,但 JWT 可能包含用户 ID、角色、权限和系统标识等信息。

在开发环境中,使用在线页面进行本地解析通常已经足够方便。

但在下面这些场景中,离线工具会更合适:

  • 公司内部系统不允许访问外网
  • Token 中包含内部业务字段
  • 正在排查生产环境问题
  • 企业有严格的数据安全要求
  • 开发电脑需要断网操作
  • 不希望把 Token 粘贴到第三方网站
  • 需要长期固定使用一套开发工具

因此,JavaPub Tools 同时提供了 Windows 桌面离线版。

桌面版基于 Electron 打包,直接加载项目中的本地静态页面。JWT 的解析逻辑运行在本地浏览器内核中,不需要把 Token 上传到服务器。项目目前自动构建 Windows x64 安装版和便携版。


九、如何下载离线桌面版?

打开项目的 GitHub Releases 页面:

下载 JavaPub Tools 桌面版

目前主要提供两种 Windows x64 版本。

安装版

文件名称类似:

JavaPub Tools-日期.commit-windows-x64-setup.exe

适合长期使用。

双击安装后,可以从桌面或开始菜单打开。


便携版

文件名称类似:

JavaPub Tools-日期.commit-windows-x64-portable.exe

便携版一般不需要传统安装,下载后可以直接运行,也方便放在移动硬盘或者开发工具目录中。


Windows 出现安全提示怎么办?

由于目前发布的安装包没有配置商业代码签名证书,Windows 可能会显示 SmartScreen 提示。

这是未签名应用比较常见的情况,并不直接表示软件存在病毒。项目 README 也明确说明,目前自动发布的是 Windows x64 未签名包,因此系统可能出现 SmartScreen 提示。

对于安全要求较高的用户,还可以直接查看开源代码并自行构建:

git clone https://github.com/Rodert/jsonformat.git
cd jsonformat
npm ci
npm run dist:win

项目源码公开,也可以在构建前自行审查代码。


十、离线版为什么更安全?

离线版的核心优势,是整个解析过程可以在本机完成。

它不依赖远程接口,也不需要将 JWT 提交给后端服务器。

甚至可以:

  1. 先下载桌面版;
  2. 断开电脑网络;
  3. 打开 JWT 解析工具;
  4. 粘贴 Token;
  5. 完成本地解析;
  6. 使用完成后清空内容并关闭软件。

对于内部系统 Token、测试环境 Token 或生产问题排查,这种方式会更加安心。

不过,离线工具也不代表可以忽略所有安全问题。

仍然建议做到:

  • 不要把 Token 发到聊天群;
  • 不要在截图中暴露完整 Token;
  • 不要把 Token 提交到 GitHub;
  • 不要把生产 Token 写进公开文章;
  • 不要随意复制来历不明的 Token;
  • 使用完成后及时清空剪贴板;
  • Token 泄露后应尽快吊销或更换。

十一、解析 JWT 不等于验证 JWT

这里需要特别提醒一下。

当前这个工具主要负责:

Base64URL 解码和字段展示

它可以帮助我们看清楚 JWT 中保存了什么信息,但不会验证 Signature 是否合法。工具页面本身也明确提示,它不负责签名合法性验证。

也就是说,一个人完全可以自己拼接出这样的 JWT:

Header.Payload.FakeSignature

解析工具仍然可能显示出 Header 和 Payload。

但这并不代表它是一个有效的 JWT。

真正判断 Token 能不能使用,还需要服务端完成:

  • 签名算法检查
  • 密钥或公钥校验
  • Signature 验证
  • exp 过期检查
  • nbf 生效时间检查
  • iss 签发方检查
  • aud 受众检查
  • Token 吊销状态检查
  • 用户和权限状态检查

因此,不能因为一个 Token 可以被解析,就认定它是合法 Token。

也不能在服务端只解析 Payload、不校验签名。


十二、服务器时间也可能导致 JWT 失效

有时 JWT 明明刚刚生成,后端却提示:

Token expired

或者:

Token not active

这不一定是 JWT 生成逻辑有问题,也可能是服务器时间不准确。

例如:

  • 签发服务器时间快了 5 分钟;
  • 验证服务器时间慢了 5 分钟;
  • 容器时区配置错误;
  • 本地使用北京时间,服务器使用 UTC;
  • 时间戳错误地使用了毫秒;
  • 服务之间没有进行时间同步。

JWT 中的 iat、exp、nbf 一般使用秒级 Unix 时间戳。

正确示例:

1785456000

错误地传入毫秒时间戳后,可能变成:

1785456000000

两者相差 1000 倍。

如果发现解析出来的时间是几十年甚至几万年以后,首先检查是不是把毫秒时间戳当成了秒。


十三、Access Token 和 Refresh Token 有什么区别?

在完整的登录系统中,通常会同时出现两类 Token。

Access Token

Access Token 用于正常请求业务接口。

它的有效期通常较短,例如:

15 分钟
1 小时
2 小时

有效期较短,可以降低 Token 泄露后的风险。


Refresh Token

Refresh Token 用于获取新的 Access Token。

它的有效期通常较长,例如:

7 天
30 天
90 天

Refresh Token 不应该在每个业务接口中传递,只应该提交给专门的刷新接口。

一个常见流程是:

用户登录
  ↓
服务器返回 Access Token 和 Refresh Token
  ↓
前端使用 Access Token 请求业务接口
  ↓
Access Token 过期
  ↓
使用 Refresh Token 获取新的 Access Token
  ↓
继续请求业务接口

需要注意的是,Refresh Token 通常比 Access Token 更敏感,不建议随意粘贴到任何不可信的在线页面。


十四、JWT 适合保存登录状态,但不是万能方案

JWT 的优点很明显:

  • 结构简单
  • 跨语言
  • 适合前后端分离
  • 适合微服务传递身份
  • 服务端可以减少 Session 查询
  • 可以携带少量用户和权限信息

但它也有一些需要注意的问题:

  • 签发后不容易立即撤销;
  • Payload 默认可以被读取;
  • Token 太大会增加请求流量;
  • 权限变化后旧 Token 可能仍然有效;
  • 密钥泄露会造成严重安全问题;
  • 有效期设置过长会增加泄露风险。

实际项目中可以结合:

  • 较短的 Access Token 有效期
  • Refresh Token
  • Token 黑名单
  • Redis 会话状态
  • 密钥轮换
  • HTTPS
  • 设备和登录状态管理

JWT 并不是为了完全替代服务端状态,而是一种身份信息传递方式。


十五、写在最后

JWT 看起来像一段复杂乱码,但拆开后其实并不难理解。

它主要由三部分组成:

Header.Payload.Signature

其中:

  • Header 描述类型和签名算法;
  • Payload 保存用户和业务声明;
  • Signature 用来防止内容被篡改。

在接口联调时,通过解析 JWT,我们可以快速查看用户身份、角色权限、签发时间和过期状态。

JavaPub Tools 的 JWT 解析工具支持在线使用,也提供 Windows 离线桌面版。在线版适合快速调试,离线版则更适合内部系统、敏感 Token 和断网环境。

在线工具:

JavaPub JWT 解析工具

开源项目:

Rodert/jsonformat

桌面版下载:

GitHub Releases

最后再提醒一句:

JWT 能被解析,不代表签名合法;能看到 Payload,也不代表 JWT 被破解。

开发调试可以使用解析工具快速定位问题,真正的安全判断仍然必须以服务端的完整签名验证结果为准。

在这里插入图片描述

posted @ 2026-07-31 09:51  JavaPub  阅读(51)  评论(0)    收藏  举报