JWT 通常由 Header、Payload 和 Signature 三段组成,使用点号分隔。前两段只是 Base64URL 编码,可以直接读取;第三段用于验证内容是否被篡改。
三段分别保存什么
Header 描述令牌类型和签名算法;Payload 保存标准声明和业务字段;Signature 根据前两段内容和密钥计算。
Payload 可被任何拿到令牌的人解码,因此不应存放密码、密钥或不希望客户端看到的敏感信息。
常见时间与身份声明
exp 表示过期时间,nbf 表示在此时间前不可用,iat 表示签发时间;iss、aud、sub 分别描述签发方、受众和主体。
这些字段通常使用秒级 Unix 时间戳。检查过期问题时,应同时确认服务器时钟和容许的时钟偏差。
解码不能代替验签
解码只是读取内容,攻击者也能构造看起来合理的 Header 和 Payload。服务端必须使用允许的算法和正确密钥验签,并校验受众、签发方和有效期。
调试时可以在本地解析结构,但不要把生产环境令牌提交到不可信的第三方页面。
签名算法与密钥管理
HS256 等对称算法由签发方和验证方共享同一个密钥;RS256、ES256 等非对称算法使用私钥签名、公钥验证。多服务协作时,非对称方案通常更便于控制私钥暴露范围。
验证端不能无条件相信 Header 中声明的 alg。系统应配置允许的算法列表,并拒绝 none 或不符合预期的算法,避免攻击者通过修改 Header 影响验证流程。
- 密钥不要写入前端代码
- 限制允许的签名算法
- 为密钥轮换设计 kid 与公钥集合
- 日志中不要输出完整 Token
过期、尚未生效与时钟偏差
当接口返回 Token expired 时,应先把 exp 按秒级时间戳转换,确认它与当前 UTC 时间的关系。若所有令牌都提前或延后固定时间失效,通常与服务器时区或时钟同步有关。
验证端可以配置很小的时钟容差处理分布式系统的秒级差异,但不能用过大的容差掩盖时间配置问题。刷新令牌也应有独立有效期和撤销策略,而不是无限延长访问令牌。
- 确认 exp、nbf、iat 使用秒级时间戳
- 检查签发端和验证端系统时间
- 只设置合理的时钟容差
- 区分访问令牌与刷新令牌
安全调试 JWT 的步骤
优先在本地工具中解析测试环境令牌,检查三段结构、Header 算法、Payload 声明和时间字段。遇到验签失败时,再确认密钥版本、kid、公钥地址和受众配置。
如果必须分享问题截图,应遮盖完整 Token、用户标识和权限信息。仅保留经过脱敏的 Header、字段名称以及必要的时间值,通常已经足够定位格式和配置问题。
- 使用测试环境令牌
- 本地解码,不上传生产 Token
- 分别检查格式、声明和签名
- 分享前隐藏完整令牌与用户信息
立即处理
使用相关工具
常见问题
关于这个问题
JWT Payload 可以加密吗?
普通签名 JWT 不加密 Payload;如需保密应使用专门的加密方案,并控制令牌内容。
Token 能解析就代表有效吗?
不能。必须完成签名、有效期、签发方和受众等校验。
