结构
header.payload.signature
header 与 payload 是 base64url 编码的 JSON,签名使用声明的算法和密钥对 header.payload 计算。任何人都能解码前两段,只有验证方能校验签名。
验证,而不只是解码
import jwt from 'jsonwebtoken';
const claims = jwt.verify(token, publicKey, {
algorithms: ['RS256'],
issuer: 'https://auth.example.com',
audience: 'https://api.example.com',
});
只解码不验证适合调试,绝不能用于授权。必须固定可接受算法,校验 exp、nbf、iss、aud,并拒绝未知 kid 的令牌。
何时使用
使用短期 JWT 作为无状态访问令牌和服务身份。浏览器会话优先使用 HttpOnly、Secure、SameSite Cookie,而不是 localStorage,并配合刷新令牌轮换或服务端吊销。与不透明会话 ID 相比,JWT 避免每请求查库,但即时吊销更难。
陷阱
不要在声明中放密码、个人数据或密钥。把 kid 视为不可信输入,通过受控密钥集解析。时钟偏差可能使新令牌失效或接受过期令牌,应定义小的容差。JWT 不能替代对每个资源的授权检查。