Cookie、Session、Token 的区别是什么?
一则或许对你有用的小广告
欢迎 加入小哈的星球 ,你将获得: 专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目: 《Spring AI 项目实战(问答机器人、RAG 增强检索、联网搜索)》 正在持续爆肝中,基于
Spring AI + Spring Boot3.x + JDK 21..., 点击查看; - 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot3.x + JDK 17..., 点击查看项目介绍; 演示链接: http://116.62.199.48:7070/; - 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/
面试考察点
-
基础概念掌握度:面试官不仅仅是想知道你能说出三者的定义,更是想确认你是否理解它们在 Web 认证和状态管理中的角色定位,以及各自的存储位置和工作机制。
-
架构演进意识:考察你是否清楚从 Cookie + Session 到 Token 的演进过程,理解为什么现代分布式系统更倾向于使用 Token,以及这背后的技术驱动因素。
-
实践应用能力:能否根据实际场景选择合适的方案,比如单机应用用 Session、分布式系统用 Token、移动端如何处理认证等,以及了解各自的安全风险和防范措施。
核心答案
Cookie 是浏览器存储的小型数据,由服务器生成、浏览器保存;Session 是服务器端存储的会话数据,通过 Cookie 中的 SessionID 关联;Token 是无状态的身份凭证,包含用户信息且可自验证。
| 对比维度 | Cookie | Session | Token(JWT) |
|---|---|---|---|
| 存储位置 | 浏览器(客户端) | 服务器内存/Redis | 客户端(localStorage/Cookie) |
| 安全性 | 较低(容易被窃取) | 较高(数据在服务端) | 较高(签名防篡改) |
| 跨域支持 | 受同源策略限制 | 需 SessionID 跨域 | 天然支持跨域 |
| 服务器压力 | 无 | 有(需存储 Session) | 无(无状态) |
| 扩展性 | 一般 | 差(需 Session 共享) | 好(天然支持分布式) |
| 移动端适配 | 不友好 | 不友好 | 友好 |
| 典型场景 | 存储偏好设置 | 传统单体应用认证 | 分布式/移动端认证 |
一句话总结:Cookie 是容器,Session 是服务端状态,Token 是自包含凭证;现代分布式架构首选 Token。
深度解析
一、Cookie 详解
上图展示了 Cookie 的基本工作流程,整体分为以下阶段:
-
首次请求:浏览器向服务器发起请求,此时没有任何 Cookie 信息。
-
服务器设置 Cookie:服务器通过响应头
Set-Cookie返回 Cookie 数据,格式为name=value,还可设置过期时间、域名、路径、安全属性等。 -
浏览器存储:浏览器收到响应后,将 Cookie 保存在本地(内存或硬盘,取决于是否设置过期时间)。
-
自动携带:之后每次向同一域名发请求时,浏览器会自动在请求头中携带
Cookie字段,服务器据此识别用户。
Cookie 核心属性
| 属性 | 作用 | 示例 |
|---|---|---|
Expires/Max-Age | 过期时间 | Max-Age=3600(1 小时后过期) |
Domain | 作用域名 | Domain=.example.com(含子域名) |
Path | 作用路径 | Path=/admin(仅 /admin 路径生效) |
Secure | 仅 HTTPS 传输 | Secure(http 请求不携带) |
HttpOnly | 禁止 JS 访问 | HttpOnly(防 XSS 攻击) |
SameSite | 跨站限制 | SameSite=Strict(防 CSRF) |
Cookie 的局限性
- 大小限制:单个 Cookie 最大 4KB,每个域名最多 20 个 Cookie
- 安全性差:明文存储,容易被窃取或篡改
- 跨域限制:受浏览器同源策略限制
- 增加流量:每次请求都携带,增加网络开销
二、Session 详解
上图展示了 Session 的完整工作流程,整体分为以下阶段:
-
登录请求:用户提交用户名和密码进行登录。
-
创建 Session:服务器验证通过后,创建一个 Session 对象,生成唯一的 SessionID,并将用户信息存储在 Session 中。Session 可以存储在内存、文件、数据库或 Redis 中。
-
返回 SessionID:服务器通过
Set-Cookie将 SessionID 返回给浏览器,Cookie 名通常是JSESSIONID(Java)或PHPSESSID(PHP)。 -
携带 Cookie:浏览器后续请求自动携带包含 SessionID 的 Cookie。
-
查询 Session:服务器根据 SessionID 从存储中查找对应的 Session 数据。
-
返回数据:验证 Session 有效后,返回业务数据。
Session 存储方案对比
| 存储方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 内存(单机) | 速度最快 | 重启丢失、无法分布式 | 开发测试 |
| 内存(集群) | - | Session 同步复杂 | 不推荐 |
| 粘性 Session | 简单 | 负载不均衡、单点故障 | 小规模集群 |
| Redis | 快速、支持分布式 | 增加 Redis 依赖 | 推荐方案 |
| 数据库 | 持久化 | 性能较差 | 需要持久化的场景 |
Session 的局限性
- 服务器压力:大量用户同时在线时,Session 占用大量内存
- 扩展性差:分布式环境下需要 Session 共享方案(Redis、Spring Session)
- 跨域问题:前后端分离、多系统整合时处理复杂
- 移动端不友好:移动 App 无法自动管理 Cookie
三、Token 详解
上图展示了 Token(以 JWT 为例)的完整工作流程:
-
登录请求:用户提交凭证,请求登录接口。
-
生成 Token:服务器验证通过后,使用密钥生成 JWT Token,包含用户 ID、过期时间等信息,并返回给客户端。
-
客户端存储:客户端将 Token 保存在
localStorage、sessionStorage或 Cookie 中。 -
携带 Token:后续请求在
Authorization头中携带 Token,格式通常为Bearer <token>。 -
验证 Token:服务器使用密钥验证签名,解析出用户信息,无需查询任何存储。
-
返回数据:验证通过后直接返回业务数据。
JWT 结构解析
JWT 由三部分组成,用点号(.)分隔:
-
Header(头部):声明 Token 类型和签名算法,如
{"alg":"HS256","typ":"JWT"},Base64 编码。 -
Payload(载荷):存放用户数据,包括标准声明(sub、exp、iat 等)和自定义声明(用户 ID、角色等),Base64 编码。注意:不要存放敏感信息,因为可以被解码。
-
Signature(签名):对 Header 和 Payload 进行签名,防止篡改。签名算法使用服务端密钥,客户端无法伪造。
Token 的优势与局限
优势:
- 无状态:服务器不需要存储 Session,天然支持分布式
- 跨域友好:不受同源策略限制,适合前后端分离
- 移动端适配:App 可直接存储 Token,不依赖 Cookie
- 性能更好:无需每次查询 Session 存储
局限:
- 无法主动失效:Token 签发后在过期前一直有效,无法像 Session 那样直接删除
- Payload 不可变:一旦签发,内容无法修改
- 安全性依赖客户端:Token 泄露风险较高
四、三种方案对比总结
面试高频追问
-
Token 泄露了怎么办?如何实现 Token 主动失效?
方案一:黑名单机制
- 将失效的 Token 加入 Redis 黑名单,每次验证时检查
- 优点:可以精确控制;缺点:引入了状态,失去无状态优势
方案二:短有效期 + 刷新 Token
- Access Token 有效期短(如 15 分钟),Refresh Token 有效期长(如 7 天)
- Access Token 过期后用 Refresh Token 换取新的 Access Token
- 需要踢人时,直接让 Refresh Token 失效
方案三:版本号机制
- Token 中包含版本号,用户修改密码或踢人时更新版本号
- 验证时比对版本号,不一致则拒绝
-
JWT 存放在 Cookie 还是 localStorage?
存储位置 优点 缺点 推荐场景 Cookie(HttpOnly) 防 XSS、自动携带 防 CSRF 需额外处理、大小限制 Web 端推荐 localStorage 无大小限制、灵活 容易被 XSS 窃取 需配合严格 CSP 推荐:Web 端存 Cookie + HttpOnly + SameSite,移动端存本地存储。
-
如何实现单点登录(SSO)?
基于 Token 的 SSO 流程:
- 用户登录认证中心,获取 Token
- 访问其他系统时携带 Token
- 各系统验证 Token 签名即可,无需跨系统共享 Session
关键点:统一的认证中心、共享的密钥或公钥、统一的 Token 格式。
-
Session 和 Cookie 的区别?
- 存储位置:Session 在服务端,Cookie 在客户端
- 安全性:Session 更安全,Cookie 容易被窃取
- 容量:Session 无限制,Cookie 限制 4KB
- 依赖关系:Session 依赖 Cookie 传递 SessionID(也可 URL 重写)
常见面试变体
- 变体一:"为什么分布式系统要用 Token 而不是 Session?"
- 变体二:"JWT 的原理是什么?有什么优缺点?"
- 变体三:"如何设计一个安全的用户认证系统?"
- 变体四:"OAuth2.0 和 JWT 有什么关系?"
- 变体五:"Session 分布式共享有哪些方案?"
记忆口诀
三者定位:
- Cookie = "快递盒子",存客户端,容量小,每次都带
- Session = "仓库",存服务端,安全但占资源,扩展难
- Token = "通行证",自包含信息,无状态,分布式友好
选择原则:
- 单体小系统 → Session + Cookie
- 分布式/微服务 → Token(JWT)
- 移动端/跨域 → 必须用 Token
JWT 三段:头部(算法类型)+ 载荷(用户数据)+ 签名(防篡改)
总结
Cookie 是客户端存储容器,Session 是服务端会话状态,Token 是自包含的身份凭证。现代分布式架构首选 Token(JWT),因为它无状态、跨域友好、天然支持水平扩展。但 Token 无法主动失效,需要配合黑名单、刷新 Token 或版本号机制来弥补。Web 端建议将 Token 存入 HttpOnly Cookie 以防范 XSS 攻击。