A. 痛点描述(Problem)#
JWT 相关问题通常很“玄学”:
- 后端说 token 没问题,网关却返回 401
- 明明刚登录,立刻提示过期
- 同一套 token 在 A 环境能用,在 B 环境无效
- 你拿到一串长得像
xxxxx.yyyyy.zzzzz的字符串,不知道里面到底装了什么
JWT 的排错关键是:先看清 payload 里到底有什么,再谈签名与校验。把 token 拆开看,很多问题会立刻暴露。
B. 核心原理(Deep Dive)——JWT 到底由什么组成?#
JWT 通常是三段,用 . 分隔:
header:描述算法与类型payload:承载 claims(用户/权限/过期时间等)signature:签名(保证 header+payload 未被篡改)
本质上:
- header 与 payload 是 Base64(更严格说是 Base64URL)编码后的 JSON
- signature 是基于算法对前两段做的签名结果
HS256 vs RS256:你排错时必须先分清#
- HS256:对称密钥(同一把 secret 签名与验签)
- RS256:非对称密钥(私钥签名、公钥验签)
排错时高频误区:
- 把 RS256 的 token 当成 HS256 去验(或反过来)
- 配错密钥(公钥/私钥/secret 不是同一个来源)
- 环境变量里 secret 多了空格、换行、或编码不一致
C. 时间字段是“最常见的坑”:exp / iat / nbf#
JWT 常见时间 claims:
iat(Issued At):签发时间nbf(Not Before):在此时间之前 token 不生效exp(Expiration):过期时间
高频坑位:
-
单位搞错:秒 vs 毫秒
很多系统用“秒级时间戳”,有人却塞了毫秒,导致 exp 超大或超小。 -
时钟偏差:客户端/服务器/网关时间不一致
有的系统会允许一定的 leeway(容忍窗口),有的不会。 -
nbf 导致“尚未生效”
用户刚拿到 token,但 nbf 设置成未来时间,立刻 401。
D. 操作指南(Step-by-step)——用小算云箱离线解析 JWT 快速定位字段#
工具入口:JWT 离线解析
👉 立即使用:工具页面
建议按这个顺序排查:
第一步:把 token 粘贴进去,先看 payload 的关键字段#
重点检查:
iss(issuer,签发者)aud(audience,受众)sub(subject,主体)scope/roles/permissions(权限类字段)iat/nbf/exp(时间类字段)
如果 payload 的值就不符合预期(比如 aud 不对、scope 缺失),问题往往不在“签名算法”,而在“发 token 的逻辑”。
第二步:根据 header 的 alg 判断验签方式(HS/RS)#
- header 里
alg是 HS256:核对验签方使用的 secret alg是 RS256:核对验签方使用的公钥,以及 kid(如有)对应的 key 选择逻辑
第三步:对照 401 的常见原因清单做定位#
- 过期:exp 已过(或单位错误)
- 尚未生效:nbf 在未来
- 受众不匹配:aud 不包含当前服务
- 签发者不匹配:iss 与验签方配置不一致
- 签名不匹配:密钥错、算法错、token 被篡改、或 header/payload 被二次处理
E. 常见问题(FAQ)#
1)JWT 可以被“解密”吗?#
JWT 不是加密容器(标准的 JWS 是签名,不是加密)。payload 默认可被任何人 Base64URL 解码读取,所以不要放敏感信息。
2)为什么我解码后看到的中文是乱码?#
那通常是你在别处把 payload 当二进制或错误编码处理了。JWT 的 header/payload 是 JSON 文本,正常解码应当可读。
3)为什么 exp 看起来没过期却被判定过期?#
优先排查:时间戳单位(秒/毫秒)与服务器时钟偏差。
4)签名校验失败但 payload 看着没问题?#
payload 可读不代表合法。任何人都能改 payload,再重新拼回去;验签失败说明 token 不可信。
工具推荐#
- JWT 离线解析:立即使用工具
- Base64 编解码(理解 header/payload 的编码层):立即使用工具
- 时间戳转换(核对 iat/exp/nbf):立即使用:Unix 时间戳 ↔ 日期互转
