把登录认证想象成“去游乐园玩”:

  1. Session + Cookie“记名手环 + 门口查表”。你手上只有一个编号,安检员每次都要回保安室查电脑:“编号1001是买了票的张三吗?”

  2. Opaque Token“寄存牌”。你拿一个只有数字的牌子,去柜台(Redis)换取你的身份信息。牌子本身没意义,必须去柜台换。

  3. JWT“印有个人信息的防伪门票”。票上写着“我是张三,VIP用户,有效期到下午5点”,还有游乐园的防伪印章(签名)。安检员看一眼票上的字和印章就行,不用查电脑。


一、 三者深度对比(核心维度)

维度 Session + Cookie Opaque Token (Redis Token) JWT 
载体 Cookie (浏览器自动携带) HTTP Header (通常是 Authorization) HTTP Header (通常是 Authorization)
数据存在哪 服务端 (内存/数据库) 服务端 (Redis) 客户端 (Token 字符串内部)
服务器压力 (每次都要查表) (每次都要查 Redis) (只用 CPU 计算验签,不查库)
踢人/注销 极简单 (删掉服务端记录即可) 极简单 (删掉 Redis Key 即可) 极困难 (发出去的水泼出去,无法收回)
时效性 可自动续期 (滑动窗口) 可自动续期 (重设 Redis TTL) 死板 (签发时写死,过期必须换新)
跨域能力 差 (Cookie 跨域很麻烦) 极好
传输数据量 极小 (只是个 ID) 小 (只是个 Key) (包含头、载荷、签名)
适用架构 单体应用 (Monolith) 对可控性要求高的前后端分离 微服务、跨系统调用

1. JWT 标准流程
  • 登录: 用户发账号密码 -> 服务器验证 -> 生成 JWT -> 返回给前端。

  • 存储: 前端收到 JWT,存入 localStoragesessionStorage(如果是浏览器)。

  • 请求: 前端每次请求 API,在 Header 里带上 Authorization: Bearer <token>

  • 验证: 后端不查数据库,直接用密钥校验签名是否正确,并检查 exp (过期时间)。

2. 你可能会遇到的坑(以及解决方案)

问题 A:想踢掉某个违规用户,或者用户改密码了,旧 Token 还能用?

  • 原因: JWT 只要没过期,服务器验签就能通过,因为它不查数据库状态。

  • 你的对策:

    • 方案一(折中): 黑名单模式。把要踢掉的 JWT ID (jti) 存入 Redis,有效期设为 Token 的剩余时间。每次请求虽然不查用户信息,但查一下 Redis 黑名单。

    • 方案二(严谨): 版本号机制。在 JWT 里加一个 version 字段,用户表里也存一个。改密码时把用户表里的 version +1。验签时对比一下。(但这会让 JWT 失去“不查库”的性能优势)。

问题 B:JWT 里的信息太大了?

  • 原因: 有些开发者喜欢把用户的 权限列表菜单树Email 全塞进 JWT 的 Payload 里。

  • 你的对策: JWT 只存最核心的身份标识(如 userId, roleId)。其他的非高频数据,可以在前端单独调接口获取,或者后端验签拿到 userId 后再去缓存里查。

问题 C:Token 泄露了怎么办?

  • 原因: 如果存在 localStorage,容易被 XSS 攻击偷走。

  • 你的对策:

    • 短效 Token: 把 Access Token 有效期设得很短(比如 30 分钟)。

    • Refresh Token: 配合使用“双 Token 机制”。

    • HTTPS: 全程必须 HTTPS,防止网络抓包。


三、 什么时候你不该用 JWT?

虽然你现在用了 JWT,但如果你的项目符合以下特征,Opaque Token (Redis + Token) 其实比 JWT 更好:

  1. 极度敏感的系统: 比如银行后台、支付管理后台。管理员点“封号”,对方必须毫秒级下线。JWT 做不到这点(除非加复杂的黑名单)。

  2. 没有跨域/微服务需求: 如果你只是一个简单的单体后端 + Vue/React 前端,Redis Token 开发起来心智负担更小,不用处理 JWT 的续签逻辑。

  3. 带宽敏感: 也就是移动端网络环境很差,几 KB 的 Header 也是负担。

四、 总结:你的项目该怎么做?

既然已经是 JWT 了,大概率不需要重构。你只需要检查:

  1. 有没有放敏感信息? (密码绝对不能放 JWT 里!)

  2. 过期时间设了多久? (建议 Access Token 不超过 1 小时)。

  3. 如果用户反馈“填表填一半突然登录过期”, 你需要实现 Refresh Token 机制来无感续签。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐