一、为什么需要 JWT?

在前后端分离项目中,用户登录成功后,服务端需要返回一个 Token。后续请求携带该 Token,服务端据此识别用户身份。

实际上,不使用 JWT,直接使用 UUID + Redis 也完全可以实现身份认证。

两者的核心区别在于:UUID + Redis 依赖服务端存储登录状态,而 JWT 可以实现无状态认证。

二、UUID + Redis:有状态认证

认证流程:

  1. 用户登录成功,服务端生成随机 UUID。
  2. 将 UUID → userId 的映射保存到 Redis,并设置过期时间。
  3. 将 UUID 返回给前端,作为 Token。
  4. 后续请求携带 UUID,服务端查询 Redis 获取 userId。
  5. 查询成功则认证通过,否则拒绝访问。

例如,Redis 存储:

Key:   login:abc123
Value: userId=1001
TTL:   30分钟

优点:

  • 可以随时删除 Redis 中的 Token,实现退出登录、强制下线。
  • 可以灵活管理登录状态和过期时间。
  • 实现简单,Token 本身不暴露用户信息。

缺点:

  • 每次认证都需要查询 Redis。
  • 依赖 Redis 的可用性,需要维护服务端登录状态。

三、JWT:无状态认证

JWT(JSON Web Token)由三部分组成:

Header.Payload.Signature
  • Header: 声明 Token 类型和签名算法。
  • Payload: 存储 userId、角色、过期时间等信息。
  • Signature: 数字签名,用于验证 Token 是否被篡改。

认证流程:

  1. 用户登录成功,服务端生成包含 userId 等信息的 JWT。
  2. 服务端使用密钥进行签名,并返回 JWT。
  3. 前端后续请求携带 JWT。
  4. 服务端验证签名及过期时间,直接获取 userId,无需查询 Redis。

优点:

  • 无需查询 Redis 即可完成身份认证。
  • 不需要集中存储每个用户的登录状态。
  • 适合分布式系统,各服务可以独立验证 JWT。

缺点:

  • JWT 一旦签发,在有效期内难以主动撤销。
  • Payload 只是编码而非加密,不能存储敏感信息。
  • 用户角色等信息发生变化时,旧 JWT 中的信息不会自动更新。

四、两种方案对比

对比项 UUID + Redis JWT(无状态)
Token 内容 随机 UUID 用户信息 + 签名
服务端保存状态 需要 不需要
每次认证 查询 Redis 验证 JWT 签名
主动退出登录 删除 Redis 记录 需要额外撤销机制
权限变更 可更新 Redis 信息 旧 Token 信息可能过时
主要优势 登录状态管理灵活 减少集中式存储依赖

五、为什么 JWT 还要结合 Redis?

JWT 的一个问题是:用户退出登录后,已签发的 JWT 在过期前仍可能有效。

因此,一些项目会结合 Redis,实现 Token 黑名单、登录状态管理或刷新令牌机制。

但是,如果每次请求都必须查询 Redis 来判断 JWT 是否有效,那么就失去了部分无状态认证优势。

此时,直接使用 UUID + Redis 也是合理的选择。

六、总结

  • UUID + Redis: Token 是一个随机凭证,服务端通过 Redis 查询用户身份,属于有状态认证。如果项目需要灵活控制用户登录状态,可以选择 UUID + Redis;
  • JWT: Token 自身包含身份信息,并通过数字签名保证完整性,可以不依赖 Redis 完成认证。如果希望减少服务端状态存储依赖,可以选择 JWT。
  • JWT + Redis: 在 JWT 基础上引入状态管理,实现主动撤销、强制下线等功能。