前后端联调时最常做的一件事:后端返回了一个 JWT token,你要解码看看里面 payload 有没有、header 是什么算法、signature 签了没、过期时间戳什么时候。JWT 解码的坑虽然不多,但一旦踩了就莫名其妙——"明明签名是对的为什么还是 Invalid Signature"。
这篇文章把 JWT 三段的拆解讲透,配合在线解码工具把"看不懂的 token"快速变成 JSON。
JWT 三段结构
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
│ │ │
└────── header ──────┘ └────────── payload ──────────────────────────┘ └── signature ──┘
每一段都是 Base64URL 编码(注意:不是标准 Base64,有 3 处差异:- 换 +、_ 换 /、去掉了 = 填充)。
解码步骤:
- 按
.切成三段 - 对每段做 Base64URL 解码(
-→+、_→/、补=填充到 4 倍数长度) - header 和 payload 是 JSON,signature 是纯二进制字节
Header 段:算法和类型
{
"alg": "HS256", // 签名算法:HS256 / RS256 / ES256 / none
"typ": "JWT" // 类型,固定是 JWT
}
常见坑:"alg": "none" ——某些旧 JWT 库支持"无签名"模式,这种 token 任何人都能伪造。生产环境必须禁用 none 算法。
Payload 段:声明(Claims)
Payload 是自定义 JSON,没有固定字段。但 JWT 规范定义了 7 个标准声明:
| 声明 | 全称 | 含义 | 示例 |
|---|---|---|---|
iss |
Issuer | 签发者 | "https://example.com" |
sub |
Subject | 主题(通常是用户 ID) | "user:123" |
aud |
Audience | 接收方 | "api.example.com" |
exp |
Expiration | 过期时间戳(秒) | 1761800000 |
nbf |
Not Before | 生效前时间戳 | 1761796400 |
iat |
Issued At | 签发时间戳 | 1761796400 |
jti |
JWT ID | 唯一标识(防重放) | "a1b2c3d4" |
坑 1:exp 是 Unix 时间戳(秒),不是毫秒。很多人看到 10 位数字以为是毫秒就除以 1000,结果把过期时间算成 1970 年了。在线解码工具会自动把时间戳转成人类可读时间(2025-10-30 12:53:20,北京时间)。
坑 2:payload 可以放自定义字段,但敏感信息绝对不能放——payload 是 Base64URL 编码(不是加密),任何人解码就能看到。password、secret、bank_account 这种字段放进去等于公开。
Signature 段:签名校验
Signature = HMACSHA256(header + "." + payload, secret)。
签名校验的坑:
secret编码问题:某些 JWT 库用 UTF-8 字节做 secret、某些用 Base64 解码后的字节做 secret——同一个 secret 在不同库里签出的 signature 不一样。- 算法不一致:header 写
HS256但校验时用 RS256,一定校验失败。 - "签名校验"和"解码"是两件事:解码永远成功(Base64 解码),但签名校验可能失败。"token 解析成功但 Invalid Signature"是常见报错。
用在线解码工具验证
JWT 在线解码 功能:
- 自动解码三段:header / payload 的 JSON 格式化展示,signature 保持原始字符串(不解析)
- 过期时间实时提示:
exp/iat/nbf自动换算成本地时间,exp还会直接标注"剩余 XX"或"已过期" - 不做签名校验:工具不接触 secret——把密钥贴进任何第三方页面都有泄露风险,校验请用 jwt.io 或本地库完成
常见坑
- "我的 JWT 解码后为什么是乱码":payload 不是 JSON 而是纯文本,或解码用了标准 Base64 而不是 Base64URL。
- "解码成功但接口返回 401":签名校验失败(secret 错了、算法不一致、token 过期)。
- "两个人解码同一个 token 得到不同的 JSON 顺序":JSON 键顺序不影响含义,但某些库严格比对字符串时会触发问题。不要把解码后的 JSON 字符串用于比对,用 JSON 解析器比对对象。
- "为什么不能用 JWT 做会话":JWT 是无状态的(服务器不存),一旦签发就没法撤销。需要"强制下线"场景用 Session + Redis,或 JWT 加黑名单。
相关工具
- JWT 在线解码:三段解码、过期时间实时提示,只解码不校验签名
- JSON 格式化避坑:payload 解码后的 JSON 排版、转义与 BOM 问题