在这里插入图片描述

1. 引言:一张门禁卡,两个储物柜

想象你去一家大型连锁健身房。你在前台办了会员卡,前台工作人员核验你的身份后,给了你一张门禁卡(授权服务器 Session)。这张卡能让你进入任何一家分店。但当你走进具体某家分店时,你会领到一把临时储物柜钥匙(客户端 Session),这把钥匙只能打开你在这家店的柜子。门禁卡是通用的,储物柜钥匙是专用的,它们一起工作,让你既能跨店通行,又能在每家店安全存放私人物品。

在 OAuth2/OIDC 体系中,授权服务器 Session 和客户端 Session 扮演的正是这样的角色。前者是用户与认证中心的“统一门禁”,后者是用户与具体业务应用的“独立储物柜”。本文将从最基础的概念讲起,深入剖析这两类 Session 如何协同工作,实现单点登录(SSO),并解答一个核心问题:为什么有了 Token,还需要 Session?


2. 基础层:Session 与 Token 的前世今生

在理解 OAuth2/OIDC 的 Session 设计之前,我们先回顾一下 Web 应用最朴素的会话管理方式。这能帮助我们理解“为什么需要两类 Session”这个问题的历史根源。

2.1 上古时代:Session 与 Cookie 的“绑定”

早期 Web 应用很简单:用户登录后,服务器在内存中创建一个 Session 对象,生成一个随机的 Session ID,通过 Set-Cookie 返回给浏览器。浏览器保存这个 Cookie,后续请求自动携带。服务器根据 Session ID 找到对应的 Session 数据。

这种方式简单直接,但有一个致命问题:有状态。当应用从单机扩展到集群时,用户的请求可能落在不同服务器上,Session 数据不共享,用户就会被“踢下线”。

2.2 近代方案:集中式 Session 存储

为了解决集群共享问题,人们把 Session 从应用服务器内存中抽出来,放到一个集中存储中——最常见的就是 Redis。

用户

负载均衡

应用服务器1

应用服务器2

Redis

这样,任何一台服务器都能从 Redis 中读取 Session,实现了无状态的应用服务器 + 有状态的 Session 存储。这个模式至今仍在大量系统中使用,结构简单,运行高效。

2.3 微服务时代:自包含 Token 的崛起

微服务架构中,一个请求可能穿越多个服务。如果每个服务都要去 Redis 查询 Session,会带来额外的网络开销和延迟。于是,自包含 Token(如 JWT) 出现了。

Token 本身携带用户信息(如用户 ID、角色),服务端收到后直接解码验证,无需查询共享存储。这就是 无状态认证。

2.4 核心关系:Session 是“状态”,Token 是“凭证”

概念本质存储位置生命周期控制
Session会话状态(用户与系统的“连接”)服务端(内存/Redis)服务端可控,可主动销毁
Token凭证(证明“你是谁”)客户端(Cookie/Storage)由过期时间控制,难以主动撤销

理解了这个区别,我们就进入了 OAuth2/OIDC 的世界——Session 和 Token 不是替代关系,而是分工协作的关系。


3. 协议层:OAuth2 授权码流程中的“两次跳转”

OAuth2 最常用的模式是 授权码模式(Authorization Code Flow),它包含两次关键的浏览器跳转。正是这两次跳转,引出了两类 Session 的诞生。

3.1 四大角色

  • Resource Owner:终端用户(你)
  • Client:第三方应用(想用你的身份登录的 App)
  • Authorization Server:授权服务器(负责认证和颁发令牌)
  • Resource Server:资源服务器(存储你的数据)

3.2 核心流程(以“用 Google 登录某 App”为例)

授权服务器(Google) 第三方App 用户浏览器 授权服务器(Google) 第三方App 用户浏览器 点击“用Google登录” 302重定向到Google登录页 访问Google登录页 展示登录表单 输入用户名密码 创建授权服务器Session 302重定向回App,携带授权码(code) 访问回调地址,带code 后端用code换token 返回access_token + id_token 创建客户端Session 登录成功

第一次跳转:App 把用户浏览器重定向到 Google 的登录页。这一步让 Google 直接和用户交互,App 全程看不到密码。

第二次跳转:用户登录成功后,Google 把浏览器重定向回 App 预设的地址,并在 URL 上附带一个授权码(code)。注意,这里返回的是授权码,不是 token。为什么?因为 token 是敏感的,如果直接返回给浏览器,可能被截获。授权码是一次性的,且只能由 App 的后端去换 token,安全性更高。


4. 机制层:两类 Session 的诞生与协作

在 OAuth2/OIDC 流程中,实际上存在两个独立的 Session,它们各自承担不同的职责。

4.1 授权服务器 Session(IdP Session)

定义:用户与授权服务器之间的认证会话,通常以 AUTH_SESSION 为名,存储在授权服务器的域下(如 auth.example.com)。

作用:

  • 记录用户“已经登录过授权服务器”这一事实。
  • 实现 单点登录(SSO):当用户访问第二个应用时,重定向到授权服务器,服务器发现已有 AUTH_SESSION,直接跳过登录页,静默完成授权。

典型配置:

Set-Cookie: AUTH_SESSION=abc123; Domain=auth.example.com; HttpOnly; Secure; SameSite=Lax

4.2 客户端 Session(RP Session)

定义:客户端应用与用户浏览器之间的会话,存储在客户端的域下(如 app.example.com)。

作用:

  • 管理用户在具体业务应用中的登录态。
  • 存储用户身份信息(通常从 ID Token 中获取)和 Token 的引用(如 Refresh Token 的引用,而不是 Token 本身)。
  • 避免每次请求都携带 Access Token 到服务端验证,减少开销。

典型配置:

Set-Cookie: APP_SESSION=xyz789; Domain=app.example.com; HttpOnly; Secure; SameSite=Lax

4.3 为什么需要两类 Session?

维度授权服务器 Session客户端 Session
存储位置授权服务器域(如 auth.com)客户端域(如 app.com)
生命周期由授权服务器控制(如 30 分钟无操作过期)可独立设置,通常短于或等于授权服务器 Session
主要作用集中认证,实现 SSO承载业务上下文,管理 Token 引用
安全要求极高,必须 HttpOnly、Secure、SameSite高,同样需安全配置

核心原因:职责分离。

  • 授权服务器负责“你是谁”的认证,它的 Session 是跨应用的。
  • 客户端负责“你在本应用能做什么”的业务状态,它的 Session 是应用私有的。

如果只用授权服务器 Session,每个业务应用每次请求都要去授权服务器验证,性能差;如果只用客户端 Session,那就无法实现跨应用的 SSO。

4.4 SSO 的实现原理

当用户第一次登录 App A 时,授权服务器创建 AUTH_SESSION。当用户访问 App B 时:

  1. App B 将用户重定向到授权服务器。
  2. 授权服务器发现浏览器已经携带了 AUTH_SESSION 的 Cookie。
  3. 授权服务器直接完成授权(无需再次登录),返回授权码给 App B。
  4. App B 用授权码换取 Token,并创建自己的客户端 Session。

这就是 “无感单点登录” 的底层原理。


5. 工程层:Session 的生命周期与安全实践

5.1 生命周期管理

  • 授权服务器 Session:通常设置为 30 分钟无操作过期。用户长时间不活动后,需要重新登录。这是安全与体验的平衡。
  • 客户端 Session:可以设置得短一些(如 15 分钟),通过 Refresh Token 机制自动续期,确保用户在操作过程中不会突然掉线。

5.2 Token 与 Session 的配合

  • Access Token:短期有效(如 15 分钟),放在客户端 Session 中,每次请求由后端携带去调用资源服务器。
  • Refresh Token:长期有效(如 7 天),放在 HttpOnly Cookie 中(或后端存储),用于在 Access Token 过期时获取新的 Access Token。

有效

失效

有效

无效

用户

客户端应用

检查客户端Session

返回业务数据

检查Refresh Token

向授权服务器换取新Access Token

更新客户端Session

重定向到授权服务器

5.3 安全配置清单

配置项授权服务器 Session客户端 Session说明
HttpOnly✅ 必须✅ 必须防止 XSS 窃取
Secure✅ 必须✅ 必须仅 HTTPS 传输
SameSiteLax 或 StrictLax防御 CSRF
Domain父域或精确域精确域控制作用域
过期时间30 分钟无操作15 分钟或随 Refresh Token平衡安全与体验

5.4 分布式环境下的 Session 共享

授权服务器和客户端都可能部署多节点。Session 需要集中存储:

  • 授权服务器 Session:存储在 Redis 中,所有授权服务器节点共享。
  • 客户端 Session:同样可存储在 Redis,或使用 Spring Session 等框架自动管理。

6. 问题层:常见误区与澄清

6.1 误区一:ID Token 可以直接替代 Session

正解:ID Token 是 身份断言,用于证明“用户是谁”,通常是一次性使用的。客户端仍需维护自己的 Session 来管理业务上下文,否则每次请求都要验证 ID Token,增加开销。

6.2 误区二:授权服务器 Session 与客户端 Session 生命周期天然一致

正解:两者完全独立。用户可能在授权服务器上已经登出,但客户端 Session 仍然有效(直到过期);也可能授权服务器 Session 有效,但客户端 Session 因 Token 过期而失效。需要显式同步(如登出时通知各客户端)。

6.3 误区三:有了 Refresh Token,客户端就不需要 Session

正解:Refresh Token 用于获取新的 Access Token,而客户端 Session 用于存储用户身份和业务上下文。两者是不同层面的概念。

6.4 误区四:OAuth2 就是登录

正解:OAuth2 是 授权协议,解决的是“第三方应用能否访问我的资源”。OIDC 在 OAuth2 之上增加了身份认证层,才是真正意义上的“登录”。


7. 总结:一张图看懂两类 Session 的协作

层级组件职责存储生命周期
认证层授权服务器 Session集中认证,实现 SSO授权服务器域 Cookie + Redis30 分钟无操作
授权层Access TokenAPI 调用凭证客户端 Session(或内存)15 分钟
续期层Refresh Token获取新 Access TokenHttpOnly Cookie 或后端存储7 天
应用层客户端 Session业务上下文、用户信息客户端域 Cookie + Redis15 分钟(可续期)

最终结论:

  • 授权服务器 Session 是 SSO 的基石,它让用户只需登录一次,就能访问多个应用。
  • 客户端 Session 是业务应用独立运行的基础,它让每个应用有自己的登录态和上下文。
  • Token 与 Session 是配合关系,不是替代关系:Session 管理“状态”,Token 充当“凭证”。

理解这两类 Session 的分工与协作,是构建高安全、高可用的 SSO 架构的关键。无论你是在设计企业级身份平台,还是在为自己的应用接入 OAuth2/OIDC,这张“双 Session”的地图,都会让你走得更稳。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐