Sessions vs Tokens — 后端工程师完整指南
I’m ready to translate the article for you, but I don’t have the actual text of the post—only the source link you provided. Could you please paste the content you’d like translated here? Once I have the text, I’ll translate it into Simplified Chinese while preserving the formatting, markdown, and any code blocks or URLs unchanged.
🔐 什么是身份验证?
在深入会话和令牌之前,先澄清一个重要的区别:
| 概念 | 定义 |
|---|---|
| Authentication | 你是谁? |
| Authorization | 你被允许做什么? |
会话和令牌主要解决 身份验证持久化问题,因为登录后…
👉 HTTP 是无状态的 – 服务器在请求之间会忘记所有信息。
因此我们需要一种机制来记住用户。
🧠 核心问题
流程示例
- 用户使用电子邮件 + 密码登录。
- 服务器验证凭证。
- 用户发起另一个请求。
现在服务器必须知道:
👉 这是同一个已认证的用户吗?
这就是 会话 和 令牌 发挥作用的地方。
✅ 什么是会话?
**会话(session)**是一种 服务器端存储机制,用于跟踪已登录的用户。
关键概念
- 服务器 保存用户数据。
- 客户端 只保存一个 会话 ID。
会话工作原理(逐步说明)
-
用户登录 – 后端验证凭证。
-
服务器创建会话 – 例如,存储在 Redis/数据库中:
{ "session_id": "abc123", "user_id": 42, "role": "admin", "expires_at": "2026-02-01" } -
服务器将会话 ID 作为 Cookie 发送
Set-Cookie: session_id=abc123; HttpOnly; Secure -
浏览器在每次请求时自动发送 Cookie:
Cookie: session_id=abc123 -
服务器查找会话 – 若找到,则视为已认证用户。
架构视图
Client → Cookie → Server → Session Store → User
服务器负责记住用户。
🔥 会话的优势
| ✅ | 优势 |
|---|---|
| 强大的安全控制 | 通过删除会话即可立即失效(注销、密码更改、可疑活动)。 |
| 易于撤销 | 不需要像令牌那样等待过期。 |
| 成熟的生态系统 | 多种框架内置支持(Express‑session、Spring Security、Django Auth、Rails 等)。 |
❌ 会话的劣势
| ⚠️ | 缺点 |
|---|---|
| 在没有额外工作时不够可扩展 | 多台服务器需要共享存储(如 Redis),这会增加网络开销和基础设施复杂度。 |
| 有状态系统 | 服务器必须为每个活跃会话保留内存。 |
✅ 什么是 Token?
token 是由服务器签发的 自包含凭证,客户端存储并在每个请求中发送。
👉 与其在服务器上存储用户数据,token 本身携带数据。
最常见的类型是 JWT(JSON Web Token)。
JWT 结构
JWT 有三部分:
header.payload.signature
示例
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VyX2lkIjo0Miwicm9sZSI6ImFkbWluIn0.
abcXYZsignature
Token 工作原理(逐步)
-
用户登录 – 服务器验证凭证。
-
服务器生成 Token – 负载可能包含:
{ "user_id": 42, "role": "admin", "exp": 1735689600 // Unix timestamp } -
客户端存储 Token – 通常放在
Authorization头或 HttpOnly cookie 中。 -
客户端在每个请求中发送 Token:
Authorization: Bearer <token> -
服务器验证签名 – 若有效,则信任负载(无需数据库查询)。
架构视图
Client → Token → Server (verify only)
不需要服务器端内存 → 无状态。
🔑 Token 的优势
| ✅ | 优势 |
|---|---|
| 高度可扩展 | 适用于微服务、无服务器和分布式系统——无需共享会话存储。 |
| 更快(有时) | 每个请求不需要数据库读取,只进行加密验证。 |
| 非常适合 API | 完美用于移动应用、单页应用(React/Next.js)以及第三方集成。 |
❌ Token 的缺点
| ⚠️ | 缺点 |
|---|---|
| 难以撤销 | 长期有效的 JWT 不能立即失效。缓解措施:黑名单、短期过期 + 刷新 token(重新引入状态)。 |
| 攻击面更大(若使用不当) | 负载仅被 编码,而非加密——绝不要在其中存储敏感数据。 |
| Token 被盗风险 | 若被盗,攻击者将在 token 失效前保持认证。缓解措施:HttpOnly cookie、短 TTL、刷新 token 轮换。 |
⚔️ 会话 vs. 令牌 — 直接比较
| 特性 | 会话 | 令牌 |
|---|---|---|
| 存储 | 服务器 | 客户端 |
| 状态 | 有状态 | 无状态 |
| 可扩展性 | 更困难(需要共享存储) | 更容易(无需共享存储) |
| 撤销 | 容易(删除会话) | 困难(需要黑名单/短TTL) |
| 基础设施 | 需要会话存储 | 极少 |
| 最佳适用 | 传统网页应用 | API / 微服务 |
🧠 何时使用 Sessions?
Great choice for:
- ✅ MVC 或服务器渲染的应用
- ✅ 银行系统 & 管理后台
- ✅ 场景中 严格的安全控制 超过水平扩展的需求
🚀 何时应使用令牌?
理想适用场景:
- ✅ REST APIs
- ✅ 移动后端
- ✅ 微服务和 SaaS 平台
- ✅ 任何对 可扩展性 至关重要的情况
⭐ 高级洞见
会话和令牌各有其用。**“正确”**的选择取决于:
- 应用类型(网页 vs. API)
- 可扩展性需求(单服务器 vs. 分布式)
- 安全性与撤销需求(即时注销 vs. 可容忍的延迟)
通常会采用混合方案:浏览器 UI 使用会话,API 调用使用令牌。了解权衡后,你就能设计出既 安全 又 可扩展 的后端。
重要提示
许多工程师认为:
“JWT 总是更好。”
这是错误的。
无状态并不自动更优。
大型公司仍然大量使用会话,因为:
控制 > 便利。
架构是关于权衡,而不是追随潮流。
🔥 现代混合方法(非常流行)
两全其美
使用
- ✅ 短期 Access Token(5 – 15 分钟)
- ✅ Refresh Token 存储在服务器端
流程
- Access token 迅速过期。
- Refresh token 请求新的 access token。
- 如果 refresh token 泄露 → 撤销它。
好处
- ✔ 可扩展性
- ✔ 可控性
- ✔ 安全性
⚠️ 常见后端错误
| ❌ 错误 | 为什么不好 |
|---|---|
| 在 JWT 中放置密码 | 切勿在令牌中存储密码。 |
| 长期有效的令牌 | 极大的安全风险。 |
| 不使用 HTTPS | 令牌绝不能通过普通 HTTP 传输。 |
在 localStorage 中存储令牌(针对敏感应用) | 推荐使用 HttpOnly Cookie。 |
🧭 最终思维模型
- 👉 Sessions = 服务器记住你
- 👉 Tokens = 你证明自己的身份
两者都是工具。优秀的工程师会根据系统需求而非炒作来选择。
如果你掌握了这个主题,你已经在像系统设计师一样思考,而不仅仅是编码者。
关注我: