面试官:给我设计一个SSO系统,支持10个微服务,日活100万
面试官:给我设计一个SSO系统,支持10个微服务,日活100万?
你:“呃...用JWT...应该就行吧?”(手指抠紧桌角,心里慌得一批)
面试官追问:“JWT怎么做单点退出?跨域场景下Cookie怎么处理?ST票据为什么要设计成一次性的?”
你:“......”(大脑空白,完了,这offer要凉)
别慌!很多程序员对SSO的理解只停留在“用Token”的表面,却没吃透底层逻辑和生产坑。今天这篇文章,把SSO从核心原理、经典方案(CAS)、主流实现(JWT)到微服务落地扒个底朝天,下次面试直接让面试官追不上你的节奏!
一、先搞懂基础:什么是SSO?为什么需要它?
在聊技术实现前,我们先解决一个核心问题:单点登录到底是什么?
SSO(Single Sign-On),直译是“单点登录”,核心逻辑很简单:用户只需要在一个统一的认证中心登录一次,就能访问所有相互信任的系统,无需重复输入账号密码。

举个生活化的例子:你在淘宝登录后,访问天猫、支付宝、飞猪时,完全不用再重新登录——这就是SSO的典型应用。
那为什么企业必须做SSO?
两个核心痛点:
- 用户体验差
如果公司有订单、用户、支付等10个系统,用户每次访问都要输密码,迟早会被“逼疯”;
- 开发维护成本高
每个系统都单独开发一套登录、权限逻辑,重复造轮子不说,数据一致性还难保证。
一句话总结:SSO本质是“统一认证入口+信任共享”,解决“多系统登录繁琐”和“认证逻辑冗余”的问题。
二、经典方案:CAS协议,SSO的“元老级”实现
提到SSO,就绕不开CAS(Central Authentication Service,中央认证服务)协议——这是最经典、最成熟的SSO实现方案,至今仍在很多传统Web系统中使用。

1. 核心思想:一个认证中心,N个业务系统
CAS的核心设计是“剥离认证逻辑”:搞一个独立的“SSO认证中心”,所有业务系统(如系统A、系统B)都不自己处理登录,统一跳转到认证中心完成验证。
关键概念先明确,避免后面绕晕:
- TGT(Ticket Granting Ticket)
全局会话凭证,存在认证中心的Cookie里,证明用户“已经登录过认证中心”;
- ST(Service Ticket)
临时服务票据,一次性、有有效期,业务系统用它向认证中心“验明正身”。
2. 标准流程:3步实现跨系统免登
我们用“用户访问系统A→再访问系统B”的场景,看CAS如何工作:
第一步:首次登录系统A
-
用户访问系统A,系统A发现未登录,重定向到SSO认证中心,附带回调地址:
sso.com/login?redirect=systemA.com; -
用户在认证中心输入账号密码,验证通过;
-
认证中心生成TGT(全局会话),写入自己域名下的Cookie(仅sso.com可访问);
-
认证中心生成ST(临时票据),重定向回系统A:
systemA.com?ticket=ST-123; -
系统A拿着ST,通过后端接口调用认证中心验证;
-
验证通过,认证中心返回用户信息,系统A创建自己的本地Session,用户成功访问系统A。

第二步:免登访问系统B
-
用户访问系统B,系统B发现未登录,重定向到SSO认证中心;
-
认证中心检测到Cookie里有有效的TGT(证明已登录),直接生成新的ST,跳过登录页面,重定向回系统B;
-
系统B拿着ST去认证中心验证,通过后创建本地Session,用户免登访问系统B。

3. 为什么要用ST?直接传用户信息不行吗?
很多人会问:认证中心直接把用户ID、用户名放在重定向URL里,系统A不就直接能用了?何必搞ST这么复杂?
答案是安全!URL是明文传输,会被浏览器历史记录、服务器日志留存,用户信息直接暴露,风险极高。而ST的优势在于:
-
一次性有效:验证完就失效,就算被截获也没用;
-
时效性短:通常几分钟就过期,窗口风险极小;
-
后端验证:用户信息只在认证中心和业务系统的后端交互,前端完全接触不到。
4. CAS的坑:生产环境要注意什么?
CAS虽经典,但在分布式、高并发场景下有明显短板:
- 网络开销大
每个业务系统验证都要调用认证中心,高峰期容易成为瓶颈;
- 单点风险
SSO认证中心挂了,所有系统都无法登录;
- 跨域Cookie风险
TGT存在Cookie里,跨域场景下可能遭遇CSRF攻击。
于是,更适合分布式架构的“基于Token的SSO方案”应运而生,核心就是JWT。
三、主流方案:JWT,无状态的SSO实现
JWT(JSON Web Token)是目前微服务架构中最流行的SSO方案,核心优势是“无状态”——服务端不用存Session,仅凭Token本身就能完成验证。
1. JWT的结构:3部分组成的“安全令牌”
JWT是一串由“.”连接的字符串,格式为Header.Payload.Signature,每部分都有明确作用:
- Header(头部)
声明Token类型(JWT)和加密算法(如HS256),用Base64编码;
- Payload(载荷)
存放核心信息,比如用户ID、用户名、过期时间,同样Base64编码(注意:Base64是编码不是加密,可解码,别存敏感信息);
- Signature(签名)
这是JWT的“防伪核心”,并非简单加密。具体流程是:用服务端唯一密钥(如secret),通过指定算法(如HMAC-SHA256)对“Base64Url编码后的Header + 英文句号 + Base64Url编码后的Payload”进行哈希计算,得到的结果就是签名。验证时,服务端用相同算法和密钥重新计算签名,对比一致则证明Token未被篡改。
2. 实现流程:4步完成跨系统认证
-
用户在SSO认证中心登录,认证中心生成JWT,返回给前端;
-
前端存储JWT(存储位置后面详细说);
-
用户访问系统A,前端在HTTP请求头的
Authorization字段中带上JWT(格式:Bearer <token>); -
系统A用服务端密钥验证JWT签名:签名通过则解析Payload获取用户信息,直接完成认证,无需调用认证中心。
核心优势:各业务系统独立验证Token,不用依赖认证中心,性能高、扩展性好,完美适配微服务。
3. JWT的“致命缺陷”与解决方案
JWT不是银弹,最让人头疼的问题是——无法主动失效。
Session存在服务端,用户退出时直接删除就行;但JWT是无状态的,服务端不存储,一旦签发,在过期前始终有效。就算用户改了密码、Token被盗,也没法强制让它失效。
怎么解决?
3个实战方案:
- 短期有效期+Refresh Token
这是最主流的方案。将JWT有效期设为30分钟(短期,叫Access Token),同时签发一个有效期7天的Refresh Token(长期)。Access Token过期后,前端用Refresh Token静默请求认证中心换全新的Access Token。Refresh Token存在Redis里,需要失效时直接删除即可。
- 维护黑名单
把需要失效的JWT(如用户退出、密码修改)存入Redis黑名单,设置和JWT过期时间一致的有效期。业务系统验证JWT前先查黑名单,在黑名单内则拒绝访问。缺点是失去了JWT无状态的优势,适合安全性要求极高的场景。
- 动态密钥
给不同用户或角色分配不同的加密密钥,当需要让某用户的JWT失效时,直接更换该用户的密钥。但实现复杂度高,一般不推荐。
4. 灵魂拷问:JWT该存在哪里?
这是面试高频题,答案没有绝对,关键看“安全性需求”和“用户体验”的平衡。3种存储方式对比:

最佳实践:敏感系统用“HttpOnly Cookie + SameSite=Strict”(防XSS和CSRF);非敏感系统用LocalStorage,前端自行管理。
四、进阶问题:单点退出、跨域、OAuth2.0区别
搞定了登录,面试官大概率会追问这些“加分项”问题——这才是区分“会用”和“精通”的关键。
1. 单点退出:一个系统退出,所有系统都退出
单点登录对应“单点退出”(Single Sign-Out):用户在系统A退出,系统B、C也必须同步退出。4种实现方案对比:
- 方案1:前端轮询
前端定时请求认证中心查登录状态,发现失效则清除本地Token。缺点:实时性差、开销大,不推荐。
- 方案2:后端通知
用户退出系统A→系统A通知认证中心→认证中心删除TGT/Refresh Token→认证中心调用所有已登录系统的退出接口。缺点:认证中心需记录用户登录的系统,复杂度高。
- 方案3:Redis发布订阅
所有系统订阅Redis的“退出频道”→用户退出时,认证中心向频道发布“用户ID+退出指令”→各系统收到消息后删除本地Session/Token。优点:解耦、实时性好,生产环境首选。
- 方案4:JWT黑名单
用户退出时,将JWT加入Redis黑名单,各系统验证前先查黑名单。缺点:性能有损耗,适合小流量场景。
2. 跨域难题:不同域名的系统怎么共享认证?
如果系统A是order.com,系统B是user.com,完全跨域,Cookie无法共享,怎么办?3个解决方案:
- 方案1:CAS协议
不依赖Cookie,靠ST传递凭证,天然支持跨域,适合传统Web系统。
- 方案2:JWT+LocalStorage
JWT存在LocalStorage,前端通过postMessage或URL参数(不推荐,有风险)在跨域系统间传递,适合纯前端应用。
- 方案3:独立SSO域名
用统一的SSO域名(如sso.company.com)管理认证,所有系统跳转到该域名登录,登录后通过回调返回Token,兼容性最好。
3. 核心区别:OAuth2.0≠SSO
这是最容易混淆的知识点,很多人把OAuth2.0当成SSO的一种——大错特错!两者解决的问题完全不同:

记住:OAuth2.0是“授权”,SSO是“认证”。可以用OAuth2.0实现SSO,但不能说两者是一回事!
五、微服务落地:网关统一认证方案
如果你的系统是几十上百个微服务,每个服务都验证Token会导致代码冗余、维护复杂。推荐3种落地方案:
- 方案1:网关统一验证(首选)
所有请求先经过网关(如Spring Cloud Gateway),网关验证JWT有效性→解析用户信息放入请求头→下游微服务直接从请求头获取信息,无需再验证。优点:逻辑集中、性能好;缺点:网关压力大,需做好限流熔断。

- 方案2:服务独立验证
各微服务通过引入公共认证Starter(封装Spring Security+JWT),自行验证Token。优点:去中心化;缺点:代码重复,性能稍差。
- 方案3:网关+服务双重验证
网关做“Token是否有效”的粗验证,服务做“用户是否有权限访问该接口”的细验证。最安全,但性能损耗最大,适合金融级场景。
六、总结:SSO核心知识点清单
最后用一张清单帮你梳理核心考点,面试时直接套用:
- 基础概念
SSO是“一次登录访问多系统”,解决用户体验和开发成本问题;
- CAS协议
经典方案,基于TGT+ST,适合传统Web,缺点是依赖认证中心;
- JWT方案
无状态,适合微服务,核心解决“主动失效”(Refresh Token)和“存储安全”(HttpOnly Cookie)问题;
- 进阶问题
单点退出用Redis发布订阅,跨域用独立SSO域名,OAuth2.0是授权不是认证;
- 微服务落地
网关统一验证+下游服务信任网关,兼顾性能和可维护性。
下次面试官再问SSO,别再只说“用Token”了——从CAS到JWT,从登录到退出,从单体到微服务,把这些逻辑讲透,面试官只会对你刮目相看。
https://mp.weixin.qq.com/s/vX1RnyivkupIPwPXBPjfXw
更多推荐
所有评论(0)