5月29日 00:23

JWT 在生产环境有哪些常见问题?怎么解决?

JWT 生产环境最核心的问题是三个:token 无法主动撤销(签发后到过期前一直有效)、payload 明文可读(Base64 非加密,敏感信息暴露)、token 体积大影响性能(每次请求都要传 1-2KB)。对应解法:撤销用黑名单(Redis 存已注销 token,TTL 等于剩余过期时间)或短期 access token + refresh token 轮换;敏感数据只放引用 ID,详情查库;体积优化用短字段名和 ES256 算法(比 RS256 小约 50%)。## 追问**token 泄露了怎么办?**XSS 可窃取 localStorage 中的 token,CSRF 可利用 Cookie 中的 token。防护:优先用 HttpOnly + SameSite Cookie 存储,配合 CSRF Token;access token 设短过期时间(15 分钟),泄露窗口小;检测到异常时强制刷新 refresh token 使旧 access token 自然失效。**Refresh Token 轮换是什么?**每次用 refresh token 换新 access token 时,同时签发新 refresh token 并作废旧的那个。如果检测到旧 refresh token 被复用,说明泄露,立即撤销该用户所有 refresh token,强制重新登录。**JWT 验签每次都要算 HMAC,性能怎么优化?**对称算法验签很快(微秒级),一般不是瓶颈。非对称算法(RS256)较慢,可切换到 ES256。大规模场景可在 API 网关层做验签,避免业务服务重复计算。**多设备登录怎么管理?**每个设备签发独立 refresh token,服务端记录设备信息。踢下线时删除对应 refresh token,该设备 access token 过期后无法续期,自然登出。## 写段代码javascript// 黑名单撤销 + refresh token 轮换async function logout(token) { const { exp } = jwt.decode(token); await redis.setex(`bl:${token}`, exp - now(), '1');}async function refresh(oldRt) { if (await redis.get(`rt:${oldRt}`)) { await redis.del(`rt:${oldRt}`); const newRt = crypto.randomBytes(40).toString('hex'); await redis.setex(`rt:${newRt}`, 7*86400, userId); return { accessToken, refreshToken: newRt }; } throw new Error('invalid refresh token');}

标签:JWT