一、两条标准路线(日常开发二选一)
路线 1:Cookie + Session(有状态会话)
流程回顾:
- 登录成功 → 服务端生成 Session(图2),存入 Redis / 内存
- 通过Set-Cookie请求头发送sessionID 到浏览器端(图1)
- 浏览器会在每次请求中自动携带Cookie
- 服务器根据 sessionId 查询会话数据
核心: ✅ Cookie =浏览器传输载体✅ Session =服务端保存会话数据
路线 2:Token(典型 JWT,无状态认证)
流程回顾:
- 登录返回 Token 字符串
- 前端把 Token 存在 localStorage / Cookie (注意,Token也是可以存储在Cookie中的)
- 前端手动在 Header
Authorization: Bearer xxx携带 - 服务端校验签名,不需要服务端存储会话
二、登录场景案例
方案 1:Cookie + Session 完整流程
整体原理
登录后服务端生成唯一 SessionId,Session 数据保存在服务端(Redis / 内存)服务端通过Set-Cookie把 SessionId 下发浏览器,后续请求浏览器自动带上 Cookie。
步骤 1:用户登录请求
POST /login Content-Type: application/json { "username":"zhangsan", "password":"123456" }步骤 2:服务器处理
- 校验账号密码正确
- 生成唯一 SessionId:
sess_987654321abc - 服务端存储 Session(Mock Redis 数据)
Key: sess_987654321abc Value: {userId:1001, username:"zhangsan", role:"user", loginTime:"2026-08-04"} Expire: 30分钟步骤 3:下次访问需要鉴权的接口(例如 /user/info)
浏览器自动携带 Cookie,不需要前端手动处理!
请求自动带上:
GET /user/info Cookie: SESSIONID=sess_987654321abc步骤 4:服务端逻辑
读取 Cookie 里的SESSIONID→ 查询 Redis 找到会话数据 → 识别用户是 zhangsan,正常返回信息。
步骤 5:退出登录
服务端删除 Redis 中sess_987654321abc这条数据,会话失效。
缺点:集群部署需要 Session 共享;跨域场景 Cookie 传递麻烦。
方案 2:Token (JWT) 方案【方式 A:Token 存在 LocalStorage】
整体原理
登录成功,服务端生成一段自包含信息的 JWT 字符串,服务端不保存会话。 前端自己存储 Token,每次请求手动放到请求头 Authorization。
步骤 1:登录请求(和上面一样)
POST /login { "username":"zhangsan", "password":"123456" }步骤 2:服务端校验账号密码,生成 JWT(Mock Token)
此处简化模拟 JWT 字符串(真实 JWT 由三段 Base64 + 签名组成)
返回给前端:
{ "code":200, "token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEwMDEsInVzZXJuYW1lIjoiemhhbmdzYW4iLCJyb2xlIjoidXNlciIsImV4cCI6MTc4MDQwMDAwMH0.Sdfsdf234sdf" }步骤 3:前端存储
前端 JS 把 token 存入浏览器localStorage
localStorage.setItem('token','eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9......')步骤 4:请求受保护接口 /user/info
前端手动组装 Header发送请求:
GET /user/info Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEwMDEsInVzZXJuYW1lIjoiemhhbmdzYW4iLCJyb2xlIjoidXNlciIsImV4cCI6MTc4MDQwMDAwMH0.Sdfsdf234sdf步骤 5:服务端处理
- 获取 Header 中的 token
- 校验签名(不需要查 Redis / 数据库)
- 解码得到内置数据
userId:1001,username:zhangsan - 判断是否过期,返回用户信息
⚠️关键点:服务端没有保存这份 token 信息(无状态)
步骤 6:退出登录
单纯前端删除 localStorage 里的 token 即可; 缺陷:token 没过期前,服务端无法主动让它失效(需要维护黑名单 Redis)
方案 3:混合模式【Token 存入 Cookie(企业常用安全方案)】
很多项目为了防 XSS 攻击:把 JWT 放到 Cookie(HttpOnly) 区分于 Cookie+Session! Cookie 里放的是Token 字符串,不是 SessionId!
流程区别:
- 登录成功 →
Set-Cookie: access_token=xxxxJWT; HttpOnly - 浏览器自动携带 Cookie
- 服务端读取 Cookie 拿到 JWT,校验签名 ✅ 载体是 Cookie,认证方案却是 Token 路线! 👉 充分证明:Cookie 只是存储工具,不和 Session 绑定死。
三、JWT的优缺点
✅ JWT 的优点
- 无状态,服务端不用存储会话用户信息直接放在 token 里面,服务端只需要校验签名,不用去 Redis / 数据库查会话记录。扩容简单,多台机器不需要做会话共享,天然适合分布式、微服务。
- 跨端友好移动端、小程序、前后端分离项目都能用,不像 Cookie 受浏览器同源策略限制。
- 减少数据库 / 缓存查询压力解析出 token 就拿到用户信息,不用每次请求根据 sessionId 查询用户。
- 扩展性强可以在 payload 里携带用户角色、权限等附加信息。
⚠️ JWT 缺点(面试官大概率追问,一并记)
- Token 一旦下发,无法直接作废。除非维护黑名单,否则有效期内一直可用;
- 不能存敏感数据:payload 只是 base64 编码,不是加密,前端可以解码看到内容;
- 体积更大,每次请求都要携带,网络开销比单纯 sessionId 大;
- 刷新 token 机制需要额外设计。