文章目录
Web 安全与系统设计
Web存在的问题:Web 是无状态的
HTTP 协议是“无状态”的,意思是:每次请求都是独立的,服务器不会自动记住“上一次是谁来的”。
举例说明:
你访问了电商首页,下一步点进购物车,但服务器根本“不知道你是刚才那个访问首页的人”。
🚨 于是问题来了:
- 登录一次后,如何在后续请求中识别你是谁?
- 登录后你是“管理员”还是“普通用户”,怎么让系统知道?
- 如何控制你能不能查看某些敏感信息?
这就是认证、授权、鉴权、Session、Cookie、Token、鉴权这些概念诞生的原因。
解决方案
一、早期解决方案:Session + Cookie 的诞生
Session
- 服务端用来保存“用户的登录状态”
- 登录后创建一个 session,里面保存用户信息(比如用户名、权限)
Cookie
- 浏览器存储的“小纸条”,由服务器发给客户端
- 浏览器下次访问自动带上,服务器通过它知道“你是谁”
Session + Cookie 工作流程:
- 用户登录成功,服务器保存一个 Session(如:userId=1)
- 服务器发送一个 Cookie:Set-Cookie: sessionId=abc123
- 浏览器保存 Cookie
- 后续每次请求都自动带上 Cookie
- 服务器根据 sessionId 找回用户信息
场景适合:
- 传统网站:如早期的 JSP、PHP、ASP 网页
- 登录状态依赖服务端 Session 内存或 Redis
⚠️ 问题:
- Session 保存在服务端,不好扩展(如分布式服务)
- 前后端不分离,适合页面渲染型项目,不适合 App / 移动端
二、第二阶段:Token 的出现(前后端分离 + 移动端的解决方案)
为什么需要 Token?
- 前端 Vue/React,后端 SpringBoot 分开部署
- 客户端不能自动发送 Cookie(安全或跨域问题)
- 希望服务器是无状态的,方便横向扩展、容灾
什么是 Token?
- 一段字符串,用来代表用户身份
- 登录成功后由服务器生成,发给前端
- 前端以后每次请求都带上 Token(放在请求头)
JWT(JSON Web Token):主流 Token 形式
- 格式固定、支持加密、不易伪造
-通常结构为三段:header.payload.signature
Token 登录流程:
- 用户输入账号密码,后端验证成功
- 后端生成 Token 返回前端
- 前端存到 localStorage 或 sessionStorage
- 每次请求都在请求头加上 Token
- 后端解析 Token,识别用户身份
适合场景:
- 前后端分离的 Web 系统
-移动端、小程序、App
-分布式系统、微服务架构
三、分析总结:
1.早期版本:session+cookie存在的问题分析
①分布式服务
早期session+cookie无法解决分布式服务的原因:
举例如下:
你的服务不止部署在一台服务器上,而是:
用户请求 → 随机到 A 服务器 或 B 服务器 或 C 服务器(负载均衡)
Session 是默认保存在“当前服务器内存中的”,也就是说:
- 用户第一次登录 → 分配到 A 服务器 → A 创建了一个 Session
- 用户第二次请求 → 分配到 B 服务器 → B 根本没有 A 上那个 Session!
结果:用户虽然登录了,但在 B 看来是“未登录”,因为找不到 Session。
优雅解决:Token 模式
因为JWT 是“无状态”的,后端服务使用同一套验证机制。
验证过程:
- 用户登录后,生成的 JWT Token 本身就包含用户信息(如 userId、role)
- 后端只需验证 Token 是否有效,就能识别身份,无需存任何会话
- 不需要服务器保存登录状态:哪台服务器收到请求都能独立完成校验 → 完全支持分布式!
②非浏览器和前后端分离场景
App、小程序不会自动携带 Cookie
- Session 模式依赖浏览器自动发送 Cookie(尤其是跨页面请求)
- 但 App / 小程序 / Postman 这类非浏览器客户端 不会自动管理 Cookie
- 即使发送了,也很容易出现“session 丢失”、“登录失效”等问题
前后端分离:
- 前后端分离中,前端(如 localhost:8080)和后端(如 api.xx.com)是不同域名
- 跨域访问默认不会携带 Cookie
token优势:
Token 模式特点 | 对应优势 |
---|---|
登录后发一个 Token(如 JWT) | 不依赖 Cookie,跨域没问题 |
Token 放在前端(localStorage、App 本地) | 多端可统一管理 |
每次请求手动带上 Authorization: Bearer xxx |
客户端完全控制,通用性强 |
服务端无状态(不用保存登录信息) | 更适合分布式架构、微服务系统 |
网关统一拦截 Token 验证 | 方便统一接入与安全控制 |
Token 结构中可附带用户信息(如 userId、role) | 减少服务端查询 |
2.总结
项目 | Session + Cookie(传统方式) | Token(现代方式) |
---|---|---|
客户端是否自动带登录信息 | ✅ 浏览器自动带 Cookie | ❌ 客户端需手动加 Header |
是否依赖浏览器 | ✅ 是 | ❌ 否,通用性强 |
是否易于跨域 | ❌ 需特殊配置 | ✅ 天然支持 |
是否需要服务端保存状态 | ✅ 需要 | ❌ 无状态 |
是否适合分布式架构 | ❌ 不适合 | ✅ 适合 |
是否适合前后端分离 | ❌ 不适合 | ✅ 非常适合 |
是否适合 App、小程序等 | ❌ 不适合 | ✅ 非常适合 |