JWT 详解:三段结构的每一部分到底是什么
JWT 由 Header、Payload、Signature 三段 Base64URL 组成。逐段拆解结构与签名原理,讲清为什么 JWT 不能存敏感信息。
一、整体结构
一个典型 JWT 长这样:xxxxx.yyyyy.zzzzz,用点号分隔的三段:
- Header(头部):声明令牌类型与签名算法。
- Payload(载荷):实际存放的声明数据。
- Signature(签名):防篡改的签名。
前两段是 Base64URL 编码(-_ 代替 +/ 且去掉 =),解码即可读,没有任何加密。
二、Header:算法声明
解码后是一小段 JSON:
{"alg":"HS256","typ":"JWT"}
alg:签名算法。HS256(HMAC + SHA-256,对称密钥)最常见;RS256/ES256(非对称)适合多服务验签。typ:固定为 JWT。
三、Payload:声明集合
载荷就是一组键值对,标准声明(Registered Claims)有固定语义:
exp(过期时间戳)、iat(签发时间)、nbf(生效时间)sub(主体,通常是用户 ID)、iss(签发者)、aud(受众)
也可以放自定义字段如 role、username。注意:载荷只编码不加密,任何人都能读,所以绝不能放密码、手机号等敏感信息。
四、Signature:防篡改的核心
签名 = 按指定算法对前两段计算的结果:
HMAC_SHA256(base64(header) + "." + base64(payload), secret)
- 服务端持有密钥,签发时生成签名,收到请求时重算一遍比对。
- 任何人篡改了 header 或 payload,重算的签名就对不上,令牌立即失效。
- 但要注意:签名保证完整性与可信任,不保证机密性。
在线体验
不用装任何环境,直接用本站JWT 在线解码工具在线操作,数据都在浏览器本地处理,方便又安全。
常见问题
JWT 里的密码别人能看到吗?
能。前两段只是 Base64 编码,任何拿到令牌的人都能解码看到内容,所以敏感信息一律不能进 JWT,只放用户 ID、角色这类非敏感标识。
JWT 怎么主动作废?
JWT 天生无状态、过期前一直有效。常见做法:短过期时间 + refresh token 轮换;或维护黑名单(Redis 记录失效的 jti),但这会牺牲无状态优势。
alg:none 是什么坑?
老版本库允许 alg 填 none 生成无签名令牌,攻击者改掉 alg 绕过验签。现代库默认拒绝 none,选库时确认版本足够新且不允许外部传入算法。
