随着分布式系统、微服务架构和多子系统协作的普及,单点登录(SSO,Single Sign-On)成为连接各模块间身份认证的重要方式。SSO 的核心目标是在不同系统之间共享登录状态,用户只需登录一次,就能访问多个子系统,而无需重复验证。
实现 SSO 的方式有多种,在实际工程中,关于 Session+Cookie、单 Token、双 Token 三种常见方案常被拿来讨论。它们各有优缺点和适用边界。本文将从技术原理、典型流程、安全性、扩展性、落地难度等维度,对这三种方案进行系统对比,并给出选型建议。
三种模式原理与流程
1. Session + Cookie 模式(也称状态模式)
原理
-
用户首次登录时,认证中心(或身份提供者 IdP)在服务器端创建一个 Session(会话状态存储),生成一个 SessionID(或 session token)。
-
服务器将 SessionID 放入一个 Cookie(通常带 HttpOnly、Secure、SameSite 设置)返回给客户端。
-
后续客户端发起跨系统访问时,会自动携带这个 Cookie(SessionID),目标系统向认证中心或共享 Session 存储验证这个 SessionID 是否有效,以判断用户是否已登录。
典型流程(简化版)
-
用户访问系统 A,被重定向到认证中心登录。
-
输入用户名/密码,认证成功后,认证中心在自身服务端建立 Session,返回一个 Set-Cookie(SessionID)给浏览器,并跳转回系统 A。
-
系统 A 从请求中读取 Cookie 中的 SessionID,向认证中心或共享 Session 存储验证其合法性,并获取用户信息。
-
当用户访问系统 B,也会携带这个 Cookie,系统 B 同样验证 Session 并允许访问。
-
登出时,认证中心销毁服务器端 Session,并通知各系统(或各系统做到定期同步、轮询)失效。
特征
-
是最传统、最直观的状态管理方式
-
需要服务端维护 Session 状态
-
跨域设置 Cookie 时需注意域名、路径、安全策略
2. 单 Token 模式(无状态 Token)
原理
-
用户登录成功后,认证中心生成一个 Token(如 JWT、Opaque Token 等),其中包含用户身份、权限、过期时间等信息。
-
将这个 Token 返回给客户端(通常放在 HTTP header 或前端存储)。
-
后续客户端访问子系统时,携带这个 Token(例如 Authorization: Bearer <token>)。
-
各子系统通过验证这个 Token(验证签名 / 校验真实性 / 检查过期)以判断用户身份,无需依赖服务端 Session 存储。
典型流程(简化版)
-
用户访问系统 A,被重定向到认证中心登录。
-
用户登录成功后,认证中心返回一个 Token 给客户端。
-
客户端存储 Token(例如浏览器端 localStorage、内存或 Cookie),后续请求带上 Token。
-
子系统验证 Token 后获取用户信息并允许访问。
-
如果要登出,可以让客户端清除 Token 或令认证中心将其加入黑名单;也可以设计短生命周期 Token + 刷新机制。
特征
-
无状态架构,不依赖统一 Session 存储
-
扩展性好,适合微服务、跨语言系统、移动端场景
-
Token 一旦被盗,攻击者可凭借其访问子系统(如果防护不完善)
-
通常结合短生命周期 + 刷新机制 + 撤销机制使用
3. 双 Token 模式(Access Token + Refresh Token)
原理
双 Token 模式是在单 Token 基础上的一种强化设计,用两个不同用途的 Token 来分担职责与安全边界:
-
Access Token:短生命周期、高频使用,用于访问各子系统
-
Refresh Token:相对较长生命周期、仅用于换取新的 Access Token,不直接用于访问子系统
认证中心负责颁发这两种 Token,客户端保存并管理它们的生命周期。子系统只认可 Access Token。若 Access Token 过期,客户端使用 Refresh Token 向认证中心申请新 Access Token。若 Refresh Token 也失效,则需要重新登录。
典型流程(简化版)
-
用户登录成功,认证中心返回一对 Token:Access Token 和 Refresh Token。
-
客户端保存这两个 Token(通常 Refresh Token 存储在更加安全的位置)。
-
后续请求携带 Access Token,子系统验证后返回响应。
-
如果 Access Token 到期,客户端检测并自动用 Refresh Token 请求新的 Access Token。
-
若 Refresh Token 也失效或被撤销,则客户端需要重新登录。
-
登出时同时将 Access Token 和 Refresh Token 作废。
特征
-
兼顾性能和安全:Access Token 有短生命周期,减少被滥用风险
-
Refresh Token 可以设置更严格的使用策略(如绑定客户端、IP、设备)
-
可支持 Token 撤销、黑名单机制
-
实现稍复杂,需要处理刷新频率、并发刷新冲突、撤销策略等
优缺点分析对比
下面从多个维度对三种方案做对比:
安全性
-
Session + Cookie
-
优点:Session 存储在服务器端,更易于统一管理与销毁;Cookie 可设置 HttpOnly、Secure 等属性,防止 XSS 读取。
-
缺点:如果 Cookie 被盗(如 XSS 漏洞、Cookie 劫持),可伪造登录状态;跨域 Cookie 支持不稳定;Session 存储需要同步或共享,分布式环境下容易成为性能瓶颈。
-
在跨域场景中,Cookie 被浏览器策略限制(SameSite、第三方 Cookie 被阻止)可能带来兼容性问题。
-
-
单 Token
-
优点:无状态设计,服务器无需维护 Session 存储;适合跨语言、跨服务调用;Token 通常有签名或加密,难以篡改。
-
缺点:Token 一旦泄露,攻击者可冒用;Token 无法即时撤销(除非加入黑名单或短生命周期);如果客户端存储不当(如浏览器 localStorage 被 XSS 读取),存在泄露风险。
-
-
双 Token
-
优点:Access Token 短生命周期降低攻击窗口;Refresh Token 存放更加慎重,减少访问子系统的风险;支持 Token 撤销/黑名单机制;可增强安全控制(如绑定客户端、设备、IP 限制等)。
-
缺点:相比单 Token 增加了复杂性;刷新过程中如果设计不当可能被滥用(如被中间人截获刷新请求)。
-
总体而言,双 Token 模式在安全性和灵活性之间提供了较好的折中,成为现代 SSO / OAuth 架构中较为常见的选择。
扩展性与跨系统支持
-
Session + Cookie
在同一个顶级域名或子域名范围内较容易共享 Cookie,实现跨子系统 SSO。但在跨域、跨子域名(甚至跨组织)、微服务拆分严重的场景,Session + Cookie 的共享和同步成本很高。 -
单 Token / 双 Token
更天然支持跨域、跨服务、移动端、Server-to-Server 调用,因为 Token 本质是一个可传递的凭证,不依赖浏览器 Cookie。非常适合微服务架构、分布式系统、多终端(网页、App、API)场景。
性能与可维护性
-
Session + Cookie
需要服务端维护 Session 表、缓存或数据库,随着用户数增长,对后端资源和同步机制有压力。分布式部署下常需用集中存储或 Session 共享方案。
管理开销高(如 Session 存活管理、过期策略、内存占用、垃圾回收)。 -
单 Token / 双 Token
多为无状态验证:子系统只要验证签名或调用授权服务验证,即可判断合法性,无需服务端访问共享存储(除去黑名单或撤销逻辑)。性能开销较小,更易水平扩展。
但采用双 Token 时,需要处理刷新逻辑、并发刷新冲突、Token 黑名单、撤销机制等,复杂性略高。
用户体验
-
Session + Cookie
登录后用户在浏览器中自动携带 Cookie,不容易忘或漏带;访问子系统时体验较流畅。
但在跨域或浏览器限制第三方 Cookie 的场景下,可能触发额外跳转或失败。 -
单 Token / 双 Token
客户端需要自行管理 Token(刷新、续期、失效处理),可能在刷新时引入额外请求或短暂中断。
如果设计良好,对用户透明,也能做到无感刷新。双 Token 模式一般采用自动刷新策略,对用户感知较小。
实现、运维与安全策略
-
Session + Cookie
实现相对简单,是传统 Web 系统的默认选择。运维上需要考虑 Session 存储扩容、Session 副本同步、故障恢复、Session 清理、过期失效策略。
在多节点时需集中 Session 存储(如 Redis、数据库)或 Session 共享机制。跨地域或云环境下需考虑一致性和性能。 -
单 Token / 双 Token
实现相对复杂,需设计 Token 结构、签名/加密方案、刷新策略、撤销策略、黑名单管理、Token 存储策略(客户端/后端)等。
还需防范 Token 重放、滥用、刷新暴力等安全风险。需设计 Token 过期、撤销、刷新机制等边界。
如何选?选型建议与参考
在实际项目中,选择哪种 SSO 模式,应根据系统规模、业务特点、安全要求、运维能力、架构演进方向等权衡。下面是一些建议思路:
-
如果系统结构较为单一、模块相对紧密、用于内部系统或者子系统间共享域名较好(同域名 / 子域)
可优先考虑 Session + Cookie 模式。其实现简单、调试方便、安全控制容易落地,是一种稳妥选择。 -
如果系统已经向微服务、API 驱动、跨语言、多终端(网页 + 移动端)方向发展
倾向使用 Token 模式。其中,若安全要求较高、希望控制访问有效期、支持撤销机制,可使用 双 Token 模式;若简单场景、对安全容忍度较高,则单 Token 也可满足。 -
当系统对安全风险、滥用、Token 被盗管控要求较高
双 Token 是更安全、可控的选择。Access Token 有短生命周期,Refresh Token 用于续期,更容易做客户端绑定、撤销管理等策略。 -
若系统已有类似体系(比如已在使用 OAuth、OpenID Connect)
可结合标准的令牌机制,优先考虑 Token / 双 Token 模式,以遵循生态化标准。 -
考虑运维成本、团队能力、复杂度
如果团队资源有限、对 Token 架构不够熟悉,那么 Session + Cookie 是一种“稳妥起步”方案。随着业务成熟,可以逐步过渡到 Token / 双 Token 架构。 -
混合模式 / 渐进迁移
在现实项目中,可以采用渐进迁移策略:初期使用 Session + Cookie 做登录态管理,后续核心接口或微服务间通信逐步切换为 Token 验证;再逐步加入刷新 / 撤销机制,到最终演进为双 Token 架构。
下面是一个选型参考思路:
-
规模小、业务集中、Web 为主 → Session + Cookie 优先
-
多子系统、跨域场景、API 驱动 → Token / 双 Token 优先
-
安全要求高、需支持 Token 撤销 / 控制 → 双 Token 优先
-
团队熟悉度偏低 → 开始用 Session 模式,后期升级
-
准备跨平台、移动端扩展 → 从一开始就选 Token / 双 Token
落地注意事项与实践建议
在实际编码与运维过程中,还需注意以下几个关键点:
-
Domain / Cookie 设置
使用 Session + Cookie 模式时,跨子域名共享 Cookie 要设置合适的 domain、path,同时注意 SameSite、Secure、HttpOnly 等属性。现代浏览器对跨站 Cookie 的策略越来越严格,须兼顾兼容性。 -
Token 存储安全
对于 Token 模式,客户端存储(如 localStorage、sessionStorage、Cookie)都存在风险。若放在 JavaScript 可访问区域,要注意 XSS 防护;若放 Cookie,则要限制作用域并设置 HttpOnly/Secure 属性。 -
刷新并发冲突
在双 Token 模式中,如果多个请求同时发现 Access Token 过期,可能触发多个刷新请求。要设计防重入 / 排队机制,避免重复刷新导致混乱。 -
Token 撤销 / 黑名单
对于敏感操作或强制登出场景,要支持将某些 Token 撤销(加入黑名单)。这通常需要认证中心或 Token 验证中心做一次黑名单检查(有状态开销)。可以对 Refresh Token 做撤销,Access Token 多做短期有效,这样检查代价可控。 -
短生命周期 + 续期策略
Access Token 时间不宜过长,一般控制在几分钟到几小时级别。Refresh Token 可稍长(几天或数天)。客户端应在 Token 快到期时自动续期,以尽量减少登录中断感知。 -
安全防护
-
配置 HTTPS / TLS 以保证传输安全
-
避免敏感信息放在 Token 明文中(若使用 JWT,需要对敏感信息加密或不要放敏感字段)
-
检测并防范重放攻击、Token 重用、刷新滥用
-
限制 Token 使用范围,如绑定客户端、设备、IP、User-Agent 等
-
-
登出传导 / 同步登出
单点登录要考虑统一登出策略:若用户在认证中心登出,应通知各子系统清除本地状态。对于 Token 模式可能无法主动推送(子系统无状态),可以设计客户端轮询、心跳检测或注销回调机制。 -
监控与审计
对 Token 生成、刷新、使用、撤销等动作做好日志与监控,对异常使用、频繁刷新、访问失败等情况报警。
总结
-
Session + Cookie 模式:实现简单、适合单一 Web 系统 / 子系统结构稳定、业务边界清晰的场景。但在跨域、微服务、移动端扩展等场景受限较多。
-
单 Token 模式:无状态设计、跨域支持好、扩展性强,适合现代 Web + API 架构。但安全控制较弱,需要做好 Token 生命周期与撤销机制。
-
双 Token 模式:在安全性与性能之间达成折中,是目前主流的方案。短生命周期 Access Token 与长生命周期 Refresh Token 分职,既能控制风险,又能保证体验。
在实际选型时,应结合业务规模、架构演进方向、安全要求、团队能力等方面综合考量。若你正在设计或优化单点登录系统,也可先从 Session + Cookie 入门,再逐步迁移到 Token / 双 Token 架构 — 这样既降低初期复杂度,又有未来扩展空间。