Cookie、Session、Token、JWT 与 OAuth2 的区别

cookie,session,token,jwt,oauth2 有什么区别?


Cookie:HTTP 的“记忆载体”

是什么?

Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据。它本质上是一种存储机制和传输机制,而不是认证协议本身。由于 HTTP 是无状态协议,Cookie 的出现就是为了让浏览器在后续请求中自动携带这段数据,从而让服务器“记住”用户。

核心特点

  • 自动携带:浏览器会根据域名规则,在每次请求时自动将 Cookie 放入 Request Header。
  • 大小限制:通常限制在 4KB 左右。
  • 安全性属性:可通过 HttpOnly(防 XSS 读取)、Secure(仅 HTTPS 传输)、SameSite(防 CSRF)等属性增强安全。
  • 跨域限制:默认遵循同源策略,不支持跨域共享(除非特殊配置)。

工作原理

  1. 服务器通过 Set-Cookie 响应头发送 Cookie 到浏览器。
  2. 浏览器按域/路径/过期时间存储 Cookie,并在后续请求中通过 Cookie 请求头自动携带。
  3. 服务器解析请求中的 Cookie,根据内容执行个性化操作(如显示登录状态)。

一句话总结

Cookie 只是一个“信封”,里面装什么内容(Session ID 还是 Token),由开发者决定。


Session:服务端的“状态记录本”

是什么?

Session 是一种服务端状态管理机制。当用户登录后,服务器会在内存、数据库或 Redis 中创建一条会话记录,包含用户信息。然后服务器将该记录的 ID(Session ID)通过 Cookie 发送给客户端。

核心特点

  • 状态存在服务端:用户数据存储在服务器,客户端仅持有 ID。
  • 可控性:服务器可随时销毁 Session,强制用户下线。
  • 分布式挑战:多服务器架构需共享 Session 存储(如 Redis)。
  • 依赖传输载体:通常通过 Cookie 传递 Session ID,也可通过 URL 参数(不推荐)。

工作原理

  1. 用户提交登录凭证,服务器验证后创建 Session 并生成 Session ID。
  2. 服务器通过 Set-Cookie 响应头发送 Session ID 到浏览器。
  3. 浏览器在后续请求中通过 Cookie 请求头携带 Session ID。
  4. 服务器根据 Session ID 查找服务端存储的 Session 数据,验证用户身份。

一句话总结

Session 是“服务端记账,客户端只拿凭证”的经典模式。


Token:无状态的“通行证”

是什么?

Token 是一个自包含的访问凭证,通常是一串加密字符串。与 Session 不同,Token 模式下服务端不需要保存会话状态。验证 Token 的有效性完全依靠算法(签名/加密),而非查库。

核心特点

  • 无状态:服务端无需存储 Token 信息,仅需验证其合法性。
  • 轻量级:通常比 Session 更小,适合频繁传输。
  • 灵活存储:可存在浏览器 Cookie、HTTP Header(推荐)、LocalStorage 或内存中。
  • 有效期控制:通过设置过期时间限制 Token 生命周期。

工作原理

  1. 用户登录成功后,服务器生成 Token(如 JWT)并返回给客户端。
  2. 客户端存储 Token,并在后续请求中通过指定方式(如 Header)传递。
  3. 服务端接收请求后,直接验证 Token 的有效性(签名、过期时间等),无需查询数据库。

一句话总结

Token 把“查验身份”的计算压力从数据库查询转移到了 CPU 解密/验签上。


JWT (JSON Web Token):Token 的事实标准

是什么?

JWT 是 Token 的一种具体实现规范(RFC 7519)。它定义了 Token 的结构和签名方式,是目前最流行的 Token 格式。

核心特点

  • 三段式结构:Header(算法声明)、Payload(用户信息)、Signature(签名)。
  • 自描述性:Payload 包含用户身份和权限等声明(claims)。
  • 无状态:服务端无需存储 Token,仅需验证签名。
  • 跨域友好:适合前后端分离、移动端和微服务架构。

工作原理

  1. 服务器用密钥对 Header 和 Payload 进行签名,生成 Signature。
  2. 将三个部分用 Base64 编码后用 . 连接,形成 JWT。
  3. 客户端存储 JWT,并在请求中通过 Authorization: Bearer <token> 头部传递。
  4. 服务端接收 JWT 后,验证签名是否有效,解析 Payload 获取用户信息。

注意事项

  • Payload 不加密:JWT 的 Payload 是 Base64 编码的明文,不要存储敏感数据。
  • 无法主动撤销:一旦签发,除非设置极短有效期或引入黑名单机制,否则无法立即失效。
  • 签名密钥保护:密钥泄露会导致 JWT 被伪造。

一句话总结

JWT 是一种标准化的、自描述的、可验证的 Token 格式。


OAuth2:授权的“委托协议”

是什么?

OAuth2 既不是存储机制,也不是凭证格式,而是一个授权框架(RFC 6749)。它解决的核心问题是:如何让用户在不暴露密码的前提下,授权第三方应用访问自己的资源?

核心特点

  • 授权而非认证:OAuth2 负责授权第三方应用访问资源,不直接处理用户身份验证。
  • 标准化流程:定义了明确的授权流程和角色分工。
  • 多种授权模式:适应不同应用场景的需求。
  • 令牌交换:通过授权码等中间凭证换取最终的访问令牌。

工作原理

以授权码模式为例:

  1. 用户访问客户端应用,触发跳转到授权服务器(如 Google、Facebook)。
  2. 用户在授权服务器登录并授权客户端访问其资源。
  3. 授权服务器返回授权码(Authorization Code)给客户端。
  4. 客户端用授权码向授权服务器换取 Access Token 和 Refresh Token。
  5. 客户端使用 Access Token 访问资源服务器(如用户邮箱、照片)。

注意事项

  • 需配合认证协议:如 OpenID Connect (OIDC) 才能实现完整认证。
  • 密钥轮换:定期更新签名密钥以增强安全性。
  • 令牌安全:Access Token 应通过 HTTPS 传输,避免泄露。

一句话总结

OAuth2 是“我不给你密码,但我允许你代表我做事”的安全授权标准。


技术全景对比表

下表总结了五大技术的核心区别:

维度 Cookie Session Token JWT OAuth2
本质 存储/传输机制 服务端状态管理 访问凭证 Token 的标准格式 授权框架
状态 客户端存储 服务端有状态 服务端无状态 服务端无状态 协议层面无状态
存储位置 浏览器 服务器内存/Redis 客户端(LocalStorage/Cookie) 同 Token 不涉及存储
大小限制 约4KB 无限制 无限制 无限制 无限制
跨域支持 ❌ 受限 ❌ 受限 ✅ 友好 ✅ 友好 ✅ 专为跨域设计
移动端适配 ❌ 差(依赖浏览器) ❌ 差 ✅ 好 ✅ 好 ✅ 好
可扩展性 - ❌ 需共享存储 ✅ 天然支持 ✅ 天然支持 ✅ 天然支持
能否主动失效 ✅ 删除即可 ✅ 删除服务端记录 ❌ 需额外机制(如黑名单) ❌ 需额外机制(如黑名单) ✅ Refresh Token 轮换
典型用途 传递 Session ID 或 JWT 传统 Web 登录 API 认证 现代 API 认证 第三方授权/SSO
安全性 依赖属性(HttpOnly, Secure) 依赖服务端安全 依赖签名算法 依赖签名算法 依赖流程实现

数据来源:


场景化技术选型指南

传统服务端渲染 Web 应用

推荐方案:Cookie + Session

  • 原因:成熟稳定,服务端可控,适合内部系统或不需要对外暴露 API 的场景。
  • 最佳实践
    • 使用 HttpOnlySecure 属性保护 Cookie。
    • 设置合理的 Session 过期时间。
    • 在分布式环境中使用 Redis 等共享存储。

前后端分离应用

推荐方案:JWT + HTTP Header

  • 原因:无状态、易扩展、跨域友好,适合 API 驱动的现代应用。
  • 最佳实践
    • 将 JWT 存储在 HttpOnly + Secure + SameSite=Strict 的 Cookie 中,或通过 Header 传递。
    • 设置短期有效期(如15分钟),配合 Refresh Token 实现自动刷新。
    • 避免在 URL 或 LocalStorage 中存储 JWT。

移动端应用

推荐方案:JWT + 安全存储

  • 原因:轻量级、适合移动网络,且能实现离线访问。
  • 最佳实践
    • 使用 Android Keystore 或 iOS Keychain 加密存储 Token。
    • 通过 HTTPS 传输 Token,避免中间人攻击。
    • 定期刷新 Token,减少泄露风险。

微服务架构

推荐方案:JWT + OAuth2

  • 原因:无状态设计适合分布式系统,JWT 支持细粒度权限控制。
  • 最佳实践
    • 使用 OAuth2 的 ClientCredentials 模式实现服务间通信。
    • 在 JWT 中包含微服务所需的权限声明(如 read:users, write:products)。
    • 避免完全依赖网关验证,各微服务应实施细粒度授权控制。

第三方登录

推荐方案:OAuth2 + JWT

  • 原因:OAuth2 提供安全授权流程,JWT 作为 Access Token 实现无状态验证。
  • 最佳实践
    • 使用 OAuth2 的 Authorization Code 模式(推荐)或 PKCE(移动端)。
    • 授权服务器可返回 JWT 作为 Access Token,资源服务器验证签名即可。
    • 配合 OpenID Connect (OIDC) 实现完整用户认证。

企业内网 SSO

推荐方案:SSO + JWT

  • 原因:SSO 提供单点登录体验,JWT 实现跨系统无状态验证。
  • 最佳实践
    • 统一认证中心(如 Keycloak)生成 JWT 并通过 Cookie 或 Header 传递。
    • 各子系统验证 JWT 签名,无需重复登录。
    • 可结合 OAuth2 实现跨公司授权。

常见误区澄清

误区 1:“JWT 比 Session 更安全”

  • 真相:JWT 和 Session 的安全性取决于实现方式。Session 可随时在服务端销毁,而 JWT 一旦签发,在过期前无法主动撤销。因此,在敏感场景中,Session 可能更安全,但 JWT 更适合分布式系统。

误区 2:“用了 OAuth2 就不需要 JWT 了”

  • 真相:OAuth2 是授权框架,它规范了授权流程,但未限定令牌格式。JWT 是一种流行的令牌格式,常被 OAuth2 使用作为 Access Token。两者是互补关系,而非替代关系。

误区 3:“Token 应该存在 LocalStorage 里”

  • 真相:LocalStorage 易受 XSS 攻击,Token 应优先存在 HttpOnly + Secure + SameSite=Strict 的 Cookie 中,或通过 HTTP Header 传递。若必须使用 LocalStorage,应结合加密和短期有效期。

误区 4:“Cookie 就是 Session”

  • 真相:Cookie 是传输机制,Session 是服务端状态管理。Cookie 可以存储任何数据(如 JWT),而 Session 需要服务端维护状态。两者是不同层次的概念,可以独立使用或结合使用。

误区 5:“OAuth2 可以替代 JWT”

  • 真相:OAuth2 处理授权流程,JWT 是具体令牌格式。OAuth2 可以返回 JWT 作为 Access Token,两者结合使用更为常见。JWT 也可独立用于 API 认证。

技术关系图

这五者并非互斥关系,而是不同层次、不同职责的技术组件

  • Cookie 负责"搬运"
  • Session 负责"记账"
  • Token 负责"证明"
  • JWT 负责"标准化证明"
  • OAuth2 负责"制定授权规则"

它们可以组合使用,例如:

  1. 用户通过 OAuth2 授权第三方应用。
  2. 授权服务器返回 JWT 作为 Access Token。
  3. 客户端将 JWT 存储在 Cookie 中,并在请求中自动携带。
  4. 资源服务器验证 JWT 签名,无需服务端状态存储。

总结

理解这五个概念的区别,关键在于把握它们的本质定位技术层次

  • Cookie:HTTP 协议的无状态管理机制,负责数据存储和传输。
  • Session:服务端状态管理机制,依赖 Cookie 传递 ID。
  • Token:通用访问凭证,服务端无状态验证。
  • JWT:Token 的标准化实现,结构清晰且可验证。
  • OAuth2:授权框架,定义了令牌交换和资源访问的流程。

没有最好的技术,只有最适合场景的技术。选择时应考虑:

  • 安全性需求(如是否需要主动失效)
  • 扩展性需求(如是否需要支持分布式系统)
  • 跨域/移动端适配
  • 实现复杂度与维护成本
Licensed under CC BY-NC-SA 4.0
使用 Hugo 构建
主题 StackJimmy 设计