一、JWT 的三段结构
JWT(JSON Web Token,RFC 7519)是一个紧凑的自包含令牌,形如:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
用点号 . 分成三段:
- Header(头部):声明算法和类型,典型如
{"alg":"HS256","typ":"JWT"}。 - Payload(载荷):存放声明(claims),如用户 ID、签发时间、过期时间、权限范围。
- Signature(签名):对前两段的 Base64URL 结果按 Header 指定的算法做签名,用于防篡改。
三段都用 Base64URL 编码(标准 Base64 把 + 换成 -、/ 换成 _,并去掉末尾 = 填充),所以它只是「编码」,不是「加密」。
二、解码 ≠ 验签
这是最重要的概念:任何人拿到 JWT 都能 Base64URL 解码出 Header 和 Payload 的明文,不需要密钥。签名的作用是让服务端能验证「这段内容没被改过」,而不是让内容保密。所以:
- 用工具「解析 / 解码」= 把明文读出来,用于调试、查看过期时间、确认字段。
- 服务端「验签」= 用密钥重新算签名并比对,同时校验
exp、iss、aud等声明,才决定是否放行。
因此把 JWT 贴进在线解析工具看结构是可以的(本地工具更安全),但绝不能把生产环境的有效 token 贴到第三方网站——那等于把登录凭证交出去。本站 JWT 解析工具 全部在浏览器本地解码,不上传数据。
三、常见 Payload 字段
exp(expiration):过期时间,秒级时间戳。iat(issued at):签发时间,秒级时间戳。nbf(not before):在此时间之前不生效。sub(subject):主题,通常是用户 ID。iss(issuer):签发方;aud(audience):接收方。jti:令牌唯一 ID,用于防重放 / 黑名单。
exp、iat、nbf 都是秒级 Unix 时间戳(10 位),不是毫秒,也不是日期字符串。用 时间戳转换 把 exp 转成日期,就能立刻知道 token 什么时候失效。注意有些框架签发的是 13 位毫秒值,属于自定义实现,解析时要看位数。
四、安全注意事项
- 不要在 Payload 放密码、身份证号等敏感信息:内容是明文可读的。
- 警惕
alg: none与算法混淆攻击:服务端必须强制白名单校验算法,不能信任 Header 里客户端声明的alg。 - 签名密钥要足够长并妥善保管;HS256 是对称密钥,RS256 用私钥签、公钥验,多服务场景更适合后者。
- JWT 一旦签发,在
exp之前天然无法「注销」,需要配合短有效期 + Refresh Token 或服务端黑名单。 - 务必走 HTTPS,令牌放在
Authorization: Bearer头里比放 URL 参数安全。
五、调试流程建议
拿到 token 后:先本地解码确认三段是否完整、Header 算法是否符合预期;再把 exp / iat 转成可读时间判断是否过期;如果接口仍返回 401,问题多半在验签密钥、iss/aud 不匹配或服务器时钟偏移,而不是 token 本身格式有误。需要自己造签名做接口联调时,可以配合 HMAC 生成 与 Base64 编解码 复核编码结果。
小结
JWT = Base64URL 编码的三段明文 + 一段防篡改签名;解码是给人看的,验签是给服务端判的;exp 是秒级时间戳。把这三点分清楚,调试登录态会顺畅很多。