一、为什么需要 JWT?
在前后端分离项目中,用户登录成功后,服务端需要返回一个 Token。后续请求携带该 Token,服务端据此识别用户身份。
实际上,不使用 JWT,直接使用 UUID + Redis 也完全可以实现身份认证。
两者的核心区别在于:UUID + Redis 依赖服务端存储登录状态,而 JWT 可以实现无状态认证。
二、UUID + Redis:有状态认证
认证流程:
- 用户登录成功,服务端生成随机 UUID。
- 将
UUID → userId的映射保存到 Redis,并设置过期时间。 - 将 UUID 返回给前端,作为 Token。
- 后续请求携带 UUID,服务端查询 Redis 获取 userId。
- 查询成功则认证通过,否则拒绝访问。
例如,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 是否被篡改。
认证流程:
- 用户登录成功,服务端生成包含 userId 等信息的 JWT。
- 服务端使用密钥进行签名,并返回 JWT。
- 前端后续请求携带 JWT。
- 服务端验证签名及过期时间,直接获取 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 基础上引入状态管理,实现主动撤销、强制下线等功能。
浙公网安备 33010602011771号