别用 JWT 管理用户会话
参考Stop using JWT for sessionsjoepie912016参考Stop using JWTs!samsch一句话结论JWT 不适合用来维持用户登录状态。它本来就不是为持久会话设计的真正干这件事的工具是服务端 Session Cookie而且这套方案已经用了几十年。先把概念对齐。很多人把「Cookie vs JWT」拿来对比这本身就不对——Cookie 是存储/传输机制JWT 是带签名的令牌格式两者不是对立关系。真正该比的是无状态 JWT会话数据直接编码进 Token 里有状态 JWTToken 里只放一个 Session ID数据仍在服务端传统 Session Cookie一个可选签名的Session ID数据同样在服务端本文不是说 JWT 永远不该用而是别把它当会话机制。那样做既不合适还有安全隐患。常见误区「无状态更好扩展」——只有无状态 JWT 在技术上才略沾边但绝大多数应用根本到不了那个规模。单机多进程用 Redis 存 Session多机再挂一台 Redis现有框架都支持得很好。真到了要换方案的时候全员登出一次就能迁移不值得为了「未来可能」提前背上 JWT 的坑。「JWT 更简单、更灵活、更安全」——恰恰相反。框架自带的 Session 开箱即用灵活度上 Session 本来就能存任意数据安全上好的 Session 实现同样会用签名 Cookie「用了密码学」不等于更安全。把 JWT 塞进 Local Storage 反而更危险——任何能执行 JS 的 XSS 都能把 Token 读走而 HttpOnly Cookie 天生防这个。「JWT 自带过期不用管 Session 清理」——服务端过期同样好做而且能在过期时清理数据库里的 Session 数据无状态 JWT 过期前服务端毫无办法。「用 JWT 就不用 Cookie 同意弹窗」——错。法规管的是持久标识符跟你怎么存无关。功能性登录态本来就不需要额外同意追踪分析才需要换 JWT 也逃不掉。「放 Local Storage 能防 CSRF」——CSRF 要靠 CSRF Token 防跟 Session 机制无关。JWT 放 Cookie 一样有 CSRF放 Local Storage 则强依赖 JS还引入 XSS 风险。正确的 CSRF 缓解只有一种CSRF Token。「移动端/禁 Cookie 用户更适合 JWT」——移动浏览器和 HTTP 客户端都支持 Cookie禁 Cookie 的用户通常也会禁 Local Storage。后端对移动端和 Web 端可以同一套 SessionCookie 对 HTTP 客户端来说就是普通请求头每次带上即可。真正的代价体积大。无状态 JWT 把用户信息全塞进 Token很容易顶破 Cookie 4KB 上限被迫改用 Local Storage——然后回到上面的安全问题。无法单独作废。Session 可以随时在服务端踢掉无状态 JWT 在过期前永远有效。用户改密码、发现账号被盗、撤销管理员权限——你都没法立刻让旧 Token 失效只能等它自然过期或者自己搭一套「黑名单」基础设施那「无状态」也就名存实亡了。数据会过期。Token 里的角色、权限、资料都是签发那一刻的快照。用户刚被降权手里还攥着写着admin的旧 Token而你又作废不了它。实现欠打磨。有状态 JWT 本质上就是 Session Cookie 的劣化版——功能一样却少了 express-session 这类久经沙场、反复修漏洞的实现。自己撸一套很容易踩坑。JWT 规范本身也饱受安全圈质疑早期甚至允许alg: none伪造 Token整体设计面向的是极短寿命大约 5 分钟以内的凭证不是长登录态。那 JWT 适合什么适合一次性、短时效的授权凭证而不是持久会话。典型场景文件下载应用服务器验证登录后发一个几分钟有效的下载 Token无状态的下载服务器验签后直接吐文件单点登录中转Google 浏览器里用的是普通 Cookie SessionJWT 只在跨服务传递「刚登录成功」这一下随后各产品各自建 Session微服务内部网关验完 Session 后用短寿命 Token 在内部服务间传递身份避免每个服务都查一遍 Session 库——但即便这里内网 API Key 明文传用户 ID 往往也够未必非 JWT 不可好的 JWT 用法有几个共同点短命、单次或极少次使用、应用本身仍用 Session 管登录。该怎么做直接用框架自带的 Session。对于 Javaer 来说 SpringBoot 封装的非常好引入几个依赖写几行代码就搞定了如果想要保存到 Redis 也是引入一个依赖的事情非常方便总结Cookie 是旧技术但旧不等于差。安全领域久经考验、没被打穿往往比「新且未经充分检验」可靠得多。Session 和 JWT 可以并存各干各的——只是别把 JWT 当长期登录凭证。 用户登录这件事交给 Session 就好。