登录方式:JWT(JSON Web Token), Session + Cookie 和 Opaque Token(不透明令牌/引用令牌)
把登录认证想象成“去游乐园玩”:
-
Session + Cookie:“记名手环 + 门口查表”。你手上只有一个编号,安检员每次都要回保安室查电脑:“编号1001是买了票的张三吗?”
-
Opaque Token:“寄存牌”。你拿一个只有数字的牌子,去柜台(Redis)换取你的身份信息。牌子本身没意义,必须去柜台换。
-
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,存入
localStorage或sessionStorage(如果是浏览器)。 -
请求: 前端每次请求 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 更好:
-
极度敏感的系统: 比如银行后台、支付管理后台。管理员点“封号”,对方必须毫秒级下线。JWT 做不到这点(除非加复杂的黑名单)。
-
没有跨域/微服务需求: 如果你只是一个简单的单体后端 + Vue/React 前端,Redis Token 开发起来心智负担更小,不用处理 JWT 的续签逻辑。
-
带宽敏感: 也就是移动端网络环境很差,几 KB 的 Header 也是负担。
四、 总结:你的项目该怎么做?
既然已经是 JWT 了,大概率不需要重构。你只需要检查:
-
有没有放敏感信息? (密码绝对不能放 JWT 里!)
-
过期时间设了多久? (建议 Access Token 不超过 1 小时)。
-
如果用户反馈“填表填一半突然登录过期”, 你需要实现 Refresh Token 机制来无感续签。
更多推荐




所有评论(0)