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/

面试考察点

  1. 基础概念掌握度:面试官不仅仅是想知道你能说出三者的定义,更是想确认你是否理解它们在 Web 认证和状态管理中的角色定位,以及各自的存储位置和工作机制。

  2. 架构演进意识:考察你是否清楚从 Cookie + Session 到 Token 的演进过程,理解为什么现代分布式系统更倾向于使用 Token,以及这背后的技术驱动因素。

  3. 实践应用能力:能否根据实际场景选择合适的方案,比如单机应用用 Session、分布式系统用 Token、移动端如何处理认证等,以及了解各自的安全风险和防范措施。

核心答案

Cookie 是浏览器存储的小型数据,由服务器生成、浏览器保存;Session 是服务器端存储的会话数据,通过 Cookie 中的 SessionID 关联;Token 是无状态的身份凭证,包含用户信息且可自验证。

对比维度CookieSessionToken(JWT)
存储位置浏览器(客户端)服务器内存/Redis客户端(localStorage/Cookie)
安全性较低(容易被窃取)较高(数据在服务端)较高(签名防篡改)
跨域支持受同源策略限制需 SessionID 跨域天然支持跨域
服务器压力有(需存储 Session)无(无状态)
扩展性一般差(需 Session 共享)好(天然支持分布式)
移动端适配不友好不友好友好
典型场景存储偏好设置传统单体应用认证分布式/移动端认证

一句话总结:Cookie 是容器,Session 是服务端状态,Token 是自包含凭证;现代分布式架构首选 Token。

深度解析

一、Cookie 详解

上图展示了 Cookie 的基本工作流程,整体分为以下阶段:

  1. 首次请求:浏览器向服务器发起请求,此时没有任何 Cookie 信息。

  2. 服务器设置 Cookie:服务器通过响应头 Set-Cookie 返回 Cookie 数据,格式为 name=value,还可设置过期时间、域名、路径、安全属性等。

  3. 浏览器存储:浏览器收到响应后,将 Cookie 保存在本地(内存或硬盘,取决于是否设置过期时间)。

  4. 自动携带:之后每次向同一域名发请求时,浏览器会自动在请求头中携带 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 的完整工作流程,整体分为以下阶段:

  1. 登录请求:用户提交用户名和密码进行登录。

  2. 创建 Session:服务器验证通过后,创建一个 Session 对象,生成唯一的 SessionID,并将用户信息存储在 Session 中。Session 可以存储在内存、文件、数据库或 Redis 中。

  3. 返回 SessionID:服务器通过 Set-Cookie 将 SessionID 返回给浏览器,Cookie 名通常是 JSESSIONID(Java)或 PHPSESSID(PHP)。

  4. 携带 Cookie:浏览器后续请求自动携带包含 SessionID 的 Cookie。

  5. 查询 Session:服务器根据 SessionID 从存储中查找对应的 Session 数据。

  6. 返回数据:验证 Session 有效后,返回业务数据。

Session 存储方案对比

存储方式优点缺点适用场景
内存(单机)速度最快重启丢失、无法分布式开发测试
内存(集群)-Session 同步复杂不推荐
粘性 Session简单负载不均衡、单点故障小规模集群
Redis快速、支持分布式增加 Redis 依赖推荐方案
数据库持久化性能较差需要持久化的场景

Session 的局限性

  • 服务器压力:大量用户同时在线时,Session 占用大量内存
  • 扩展性差:分布式环境下需要 Session 共享方案(Redis、Spring Session)
  • 跨域问题:前后端分离、多系统整合时处理复杂
  • 移动端不友好:移动 App 无法自动管理 Cookie

三、Token 详解

上图展示了 Token(以 JWT 为例)的完整工作流程:

  1. 登录请求:用户提交凭证,请求登录接口。

  2. 生成 Token:服务器验证通过后,使用密钥生成 JWT Token,包含用户 ID、过期时间等信息,并返回给客户端。

  3. 客户端存储:客户端将 Token 保存在 localStoragesessionStorage 或 Cookie 中。

  4. 携带 Token:后续请求在 Authorization 头中携带 Token,格式通常为 Bearer <token>

  5. 验证 Token:服务器使用密钥验证签名,解析出用户信息,无需查询任何存储

  6. 返回数据:验证通过后直接返回业务数据。

JWT 结构解析

JWT 由三部分组成,用点号(.)分隔:

  1. Header(头部):声明 Token 类型和签名算法,如 {"alg":"HS256","typ":"JWT"},Base64 编码。

  2. Payload(载荷):存放用户数据,包括标准声明(sub、exp、iat 等)和自定义声明(用户 ID、角色等),Base64 编码。注意:不要存放敏感信息,因为可以被解码。

  3. Signature(签名):对 Header 和 Payload 进行签名,防止篡改。签名算法使用服务端密钥,客户端无法伪造。

Token 的优势与局限

优势

  • 无状态:服务器不需要存储 Session,天然支持分布式
  • 跨域友好:不受同源策略限制,适合前后端分离
  • 移动端适配:App 可直接存储 Token,不依赖 Cookie
  • 性能更好:无需每次查询 Session 存储

局限

  • 无法主动失效:Token 签发后在过期前一直有效,无法像 Session 那样直接删除
  • Payload 不可变:一旦签发,内容无法修改
  • 安全性依赖客户端:Token 泄露风险较高

四、三种方案对比总结

面试高频追问

  1. Token 泄露了怎么办?如何实现 Token 主动失效?

    方案一:黑名单机制

    • 将失效的 Token 加入 Redis 黑名单,每次验证时检查
    • 优点:可以精确控制;缺点:引入了状态,失去无状态优势

    方案二:短有效期 + 刷新 Token

    • Access Token 有效期短(如 15 分钟),Refresh Token 有效期长(如 7 天)
    • Access Token 过期后用 Refresh Token 换取新的 Access Token
    • 需要踢人时,直接让 Refresh Token 失效

    方案三:版本号机制

    • Token 中包含版本号,用户修改密码或踢人时更新版本号
    • 验证时比对版本号,不一致则拒绝
  2. JWT 存放在 Cookie 还是 localStorage?

    存储位置优点缺点推荐场景
    Cookie(HttpOnly)防 XSS、自动携带防 CSRF 需额外处理、大小限制Web 端推荐
    localStorage无大小限制、灵活容易被 XSS 窃取需配合严格 CSP

    推荐:Web 端存 Cookie + HttpOnly + SameSite,移动端存本地存储。

  3. 如何实现单点登录(SSO)?

    基于 Token 的 SSO 流程

    • 用户登录认证中心,获取 Token
    • 访问其他系统时携带 Token
    • 各系统验证 Token 签名即可,无需跨系统共享 Session

    关键点:统一的认证中心、共享的密钥或公钥、统一的 Token 格式。

  4. 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 攻击。