接口鉴权:Session/Cookie 与 JWT 的核心区别
接口鉴权:Session/Cookie 与 JWT 的核心区别
你说的非常对:传统 Web 项目用 Session/Cookie,前后端分离的接口项目(RESTful API)必须用 JWT,核心原因是架构变了—— 传统是服务端渲染页面,现在是前端独立、接口无状态。
我用最通俗、最核心的方式,把两者的区别讲清楚:
一、先搞懂:为什么传统接口不能用 Session?
1. Session 的工作原理(有状态)
- 浏览器登录 → 服务端生成 Session 存在内存 / 数据库
- 服务端返回一个
SessionID存在Cookie里 - 下次请求 → 浏览器自动带 Cookie → 服务端查 Session 确认身份
2. Session 致命缺点(不适合接口)
- 强依赖 Cookie:跨域、小程序、App、第三方调用都受限
- 服务端必须存状态:分布式 / 多服务器要做 Session 共享(Redis 同步)
- 前后端分离不友好:前端是纯客户端,不依赖浏览器自动带 Cookie
所以:接口鉴权必须抛弃 “服务端存状态” 的方案 → JWT 应运而生
二、JWT 是什么?(无状态)
JWT = JSON Web Token
一句话:把用户身份信息加密成一串字符串,存在客户端,服务端不存任何登录状态。
工作流程:
- 登录成功 → 服务端用密钥签发 JWT(不存任何数据)
- 前端把 JWT 存在本地(localStorage / 小程序缓存)
- 每次请求接口 → 前端手动把 JWT 放在请求头里
- 服务端只用密钥验证 JWT 是否合法,不用查库
三、Session / Cookie 与 JWT 的核心区别(一张表看懂)
表格
| 对比维度 | Session / Cookie | JWT |
|---|---|---|
| 存储位置 | 服务端存储,客户端只存 ID | 全部存在客户端,服务端零存储 |
| 状态 | 有状态(服务端要查会话) | 无状态(Stateless,接口天然支持分布式) |
| 跨域 / 跨端 | 差(依赖 Cookie,跨域限制大) | 极强(支持 Web、小程序、App、第三方接口) |
| 分布式部署 | 麻烦(需要 Session 共享) | 极简单(多台服务器直接用同一密钥验证) |
| 请求方式 | 浏览器自动带 Cookie | 前端手动传(请求头 / 参数) |
| 安全特点 | 易受 CSRF 攻击 | 无 CSRF 风险 |
| 适用场景 | 传统网站、服务端渲染 | 前后端分离、RESTful API、微服务 |
四、最关键的 3 个本质区别
1. 有无状态(最核心)
- Session:服务端必须记住你登录了(有状态)
- JWT:服务端不记得任何人,只认令牌(无状态)
→ 接口架构必须无状态,所以 JWT 是标准
2. 数据存在哪里
- Session:存在服务器
- JWT:存在客户端自己手里
3. 扩展性
- Session:服务器越多越麻烦
- JWT:随便加服务器,完全不用改代码
五、简单总结:为什么接口要用 JWT?
- 不依赖 Cookie,跨域、小程序、App 全支持
- 服务端不存登录状态,分布式 / 集群随便扩
- 标准通用,所有前后端分离架构都用它
- 安全可控,可设置过期、可加密、可防篡改
总结
- Session/Cookie:适合传统网站,服务端存状态,依赖浏览器
- JWT:适合接口鉴权,无状态、跨端、分布式友好
你可以简单记:
网站用 Session,接口用 JWT;有状态用 Session,无状态用 JWT。
<!-- JWT 工具:jjwt,Spring5 兼容 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
浙公网安备 33010602011771号