JWT 设计原理与使用指南
理解令牌的结构、签名方式和适用边界,再把它用于身份认证与服务间传递。
JWT 是什么
JWT(JSON Web Token)是一种紧凑的声明格式,可在双方之间传递经过编码并可选签名的数据。它常用于身份认证和授权。JWT 本身不负责登录、会话续期或权限管理,这些规则由应用系统实现。
常见的签名型 JWT 由三段组成,段与段之间用英文句点 . 分隔:Header.Payload.Signature。
三部分组成
Header:头部
描述令牌类型和签名算法,例如 {"alg":"HS256","typ":"JWT"}。头部 JSON 经 UTF-8 编码后使用 Base64URL 表示。
Payload:载荷
承载声明(Claim),例如用户标识、签发时间和过期时间。标准声明包括 iss、sub、aud、exp、nbf、iat、jti;也可加入应用自定义字段。
Signature:签名
签名用于检测头部或载荷是否被篡改。验证方需按可信配置重新计算并比较签名;仅解码前两段无法证明令牌可信。
编码与签名原理
Header 和 Payload 先序列化为 JSON,再分别进行 Base64URL 编码(使用 URL 安全字符,并省略末尾填充符 =)。签名型 JWT 通常对编码后的前两段计算签名:
签名输入 = BASE64URL(Header) + "." + BASE64URL(Payload)
HMAC 算法(如 HS256)使用双方共享的密钥;RSA 或 ECDSA 算法(如 RS256、ES256)使用私钥签发、公钥验证。Base64URL 不是加密:拿到令牌的人通常可以读出载荷。需要保密内容时,应使用经过规范设计的加密方案,而不是把敏感信息放进普通 JWT。
常见应用场景
- API 身份认证:客户端在请求中携带访问令牌,服务端验证签名、有效期、签发者和受众。
- 服务间授权:服务在受控边界内传递有限权限和目标服务信息。
- 一次性或短期链接:结合短有效期、受众限制和防重放设计,用于邀请、验证等流程。
JWT 不一定比服务端会话更合适。需要即时撤销、频繁变更权限或存放大量状态时,应评估服务端会话或令牌撤销机制。
常见问题
JWT 解码后为什么看得到用户信息?
因为常见签名型 JWT 的载荷只是 Base64URL 编码,不是加密。不要放入密码、密钥、个人敏感信息或其他不应被令牌持有者读取的内容。
解码成功是否代表 JWT 有效?
不是。解码只检查格式并读取 JSON。服务端还应验证签名、允许的算法、过期时间,以及 iss 和 aud 等与业务相关的声明。
exp、iat 和 nbf 分别代表什么?
exp 是过期时间,iat 是签发时间,nbf 表示在此时间之前令牌不可用。它们使用 Unix 时间戳秒数;验证时可按系统策略容忍少量时钟偏差。
JWT 被盗后能撤销吗?
签名本身不提供撤销能力。可缩短访问令牌有效期、轮换密钥,或在服务端维护撤销列表、令牌版本等状态。刷新令牌应单独保护并实施轮换。
应该把 JWT 存在哪里?
根据威胁模型选择存储方式。浏览器持久化存储可能暴露给同源脚本;Cookie 可设置 HttpOnly、Secure 和合适的 SameSite,但仍需考虑跨站请求伪造防护。避免在 URL、日志和错误上报中泄露令牌。