← 返回题目列表

Cookie、Session 和 Token 有什么区别?

高频 中等 第 7 / 32 题 更新于 2026/07/28
HTTPCookieSessionTokenJWT

简化版

它们都是为了解决 HTTP 无状态(服务器记不住你是谁)的问题。Cookie 存在客户端,每次请求自动带上,是「载体」;Session 存在服务端,靠 Cookie 里的 sessionId 关联,是「服务端记账」;Token(如 JWT)也存客户端,但自带签名、服务端不用存,是「无状态认证」。演进方向是:从「服务端存状态(Session)」走向「服务端不存状态(Token)」。

详细版

Cookie

  • 服务器通过响应头 Set-Cookie 下发,浏览器保存,之后每次请求自动带上 Cookie 头;
  • 存在客户端(浏览器),有大小限制(约 4KB);
  • 关键安全属性:HttpOnly(禁 JS 读取,防 XSS 窃取)、Secure(只在 HTTPS 传)、SameSite(防 CSRF)。

Session

  • 数据存在服务端(内存/Redis/数据库),每个会话有个 sessionId
  • 这个 sessionId 通常放在 Cookie 里发给浏览器,下次请求带回来,服务端据此找到对应的 session 数据;
  • 服务端有状态,占服务器内存;分布式部署要解决 session 共享(如集中存 Redis)。

Token(以 JWT 为例)

  • 登录后服务端签发一个 Token(含用户信息 + 签名),客户端保存(Cookie 或 localStorage),请求时带上(通常放 Authorization: Bearer <token>);
  • 服务端不存储,靠验证签名确认 Token 合法,天然适合分布式、无状态。

完整版教学

一、根本目的:给无状态的 HTTP 加上「记忆」

HTTP 是无状态的——每个请求都是独立的,服务器默认不知道「这个请求和上一个是不是同一个人发的」。但登录态、购物车这些功能需要「记住用户」。

Cookie/Session/Token 就是给 HTTP 加记忆的三种方案,核心问题是:「用户身份这个状态存在哪、怎么在每次请求里带上」。理解了这个出发点,三者的关系就清晰了——它们是同一个问题的不同解法。

二、Cookie 和 Session 是「搭档」不是「对手」

初学者常把 Cookie 和 Session 对立起来比较,其实它们经常配合工作

  • Session 负责在服务端存数据(用户信息、权限等);
  • Cookie 负责在客户端存那把「钥匙」(sessionId),并每次请求自动带上。

流程:登录成功 → 服务端创建 session、生成 sessionId → 通过 Set-Cookie 把 sessionId 发给浏览器 → 之后每次请求 Cookie 自动带上 sessionId → 服务端用它找到 session 数据、认出你是谁。

所以「Cookie 存客户端、Session 存服务端」不是二选一,而是Cookie 常常是 Session 的载体

三、Session vs Token:有状态 vs 无状态

这是这道题的重点对比,也是技术演进的核心:

维度SessionToken(JWT)
存储位置服务端存数据客户端存,服务端不存
服务端状态有状态(占内存)无状态(只验签名)
分布式扩展要解决 session 共享(Redis)天然友好,任意节点都能验
失效控制服务端删了就失效,好控制签发后难主动失效(要额外黑名单)
跨域/多端Cookie 跨域受限放 header,跨域/App 都方便

Session 有状态:服务端要存所有登录用户的会话,用户多了占内存,分布式下还要 session 共享。好处是服务端能随时让某个 session 失效(踢下线)。

Token 无状态:服务端不存,靠验证签名判断合法性,扩展性极好、适合微服务和 App。代价是难主动失效——Token 签发后在过期前一直有效,想提前踢人得额外维护黑名单,相当于又引入了状态。

四、JWT 的结构与注意点

JWT 由三段用 . 连接:Header.Payload.Signature

  • Header:算法类型;
  • Payload:存放的数据(用户 id 等),只是 Base64 编码,不是加密——所以别在里面放密码等敏感信息,谁都能解码看到;
  • Signature:用服务端密钥对前两段签名,防篡改。改了 Payload 签名就对不上。

⚠️ JWT 的 Payload 是可被解码的明文(Base64),只防篡改(靠签名),不防偷看。敏感数据别放 Payload。

五、安全:Cookie 的三个关键属性

  • HttpOnly:禁止 JavaScript 通过 document.cookie 读取,防止 XSS 攻击窃取 Cookie;
  • Secure:只在 HTTPS 连接下发送,防明文泄露;
  • SameSite:控制跨站请求是否携带 Cookie(Strict/Lax/None),是防 CSRF 的重要手段。

存登录凭证时,放 Cookie 并设 HttpOnly 能防 XSS 窃取;放 localStorage 则 JS 能读、XSS 风险更高,但不会被 CSRF 自动带上。各有权衡。

六、常见误区

  • ❌ 把 Cookie 和 Session 当对立——Cookie 常是 Session 的载体(存 sessionId)。
  • ❌ 以为 JWT 的内容是加密的——Payload 只是 Base64 编码,能被解码,别放敏感信息。
  • ❌ 以为 Token 无状态所以完美——它难主动失效,踢人要额外黑名单。
  • ❌ 以为 Session 不能用于分布式——可以,把 session 集中存 Redis 即可,只是多一层依赖。

六、常见误区与追问

考点正确口径
Cookie浏览器保存并自动随请求携带的小段数据
Session服务端保存状态,客户端通常只存 sessionId
Token客户端保存凭证,服务端校验签名或查状态
Cookie: sessionId=abc
Server session store: abc -> userId
JWT: header.payload.signature

Cookie 是传输和存储机制,Session/Token 才是身份状态方案,别把层次混在一起。

  • 误区:Cookie 和 Session 是二选一关系。 常见 Session 方案正是用 Cookie 保存 sessionId,两者经常配合。
  • 误区:Token 一定完全无状态。 JWT 可自包含,但服务端仍可能维护黑名单、刷新令牌和撤销状态。
  • 误区:JWT 内容天然保密。 JWT payload 只是 Base64URL 编码,不加密时客户端可读,敏感信息不要直接放。
  • 追问:Cookie 有哪些关键安全属性? HttpOnly 防 JS 读取,Secure 限 HTTPS,SameSite 缓解 CSRF。
  • 追问:Session 的缺点是什么? 服务端要存状态,分布式下需要共享存储或粘性会话。
  • 追问:Token 如何续期? 常用 access token 短期有效、refresh token 换新,并配合撤销和风控。

七、加强记忆

三者都为解决 HTTP 无状态、记住用户。Cookie 存客户端、自动随请求发送,常作为载体;Session 存服务端、靠 Cookie 里的 sessionId 关联,有状态占内存、可主动失效;Token(JWT)存客户端、自带签名服务端不存,无状态适合分布式、但难主动失效且 Payload 只编码不加密。演进方向是从有状态 Session 走向无状态 Token。