4. 单点登录(SSO)
🔐 一次登录,全网通行 —— 工作原理 · 实现方式 · 常见问题
4.1 SSO 工作原理
单点登录(Single Sign-On)允许用户使用一组凭据登录多个独立系统。核心是建立一个中央认证服务(CAS),所有应用信任该服务颁发的身份票据。
流程简述 用户访问应用A → 重定向至CAS登录 → CAS验证凭据 → 下发全局票据(Ticket) → 用户携带票据访问应用B/C,无需再次输入密码。
4.2 SSO 实现方式
🔹 基于 Cookie 的 SSO
在同一个父域下(如 .example.com),认证中心设置全局 Cookie,各子域共享该 Cookie 实现登录态传递。
优点:实现简单,适合同域架构。 缺点:跨域无法直接共享 Cookie,安全性依赖 Cookie 属性。
🔸 基于 Token 的 SSO
认证中心颁发签名的 Token(如 JWT),应用通过验证 Token 的签名和声明来确认身份,不依赖 Cookie 域。
优点:跨域、跨平台,无状态,适合微服务。 缺点:Token 泄露风险,需配合刷新机制。
| 特性 | 基于 Cookie | 基于 Token |
|---|---|---|
| 跨域支持 | 受限(需父域) | 天然支持 |
| 状态 | 有状态(服务端会话) | 无状态(自包含) |
| 安全风险 | CSRF、Cookie 劫持 | Token 泄露、重放 |
| 典型协议 | CAS (传统) | OIDC / JWT |
4.3 SSO 常见问题
⚠️ 会话管理
- 全局登出 (SLO):用户在一个应用登出,需通知所有关联应用销毁会话。实现复杂,常采用异步事件或轮询。
- 会话超时:IdP 会话与应用会话生命周期不一致,可能导致用户被中途要求重新登录。
- 并发限制:同一用户多地登录可能引发会话冲突,需设计策略(踢下线 / 多会话共存)。
🌐 跨域问题
- Cookie 跨域:浏览器同源策略限制,无法跨域发送 Cookie。解决方案:使用 Token 或 自定义域名统一(如
sso.company.com)。 - 重定向循环:跨域认证流程中,如果票据验证失败,可能陷入反复重定向。需设置合理的超时与错误处理。
- iframe 嵌入:第三方应用通过 iframe 嵌入 SSO 登录页,可能被浏览器阻止(X-Frame-Options / CSP)。
📄 基于 Token 的 SSO 伪代码(JWT 验证)
// 认证中心颁发 JWT
function issueToken(user) {
const payload = { sub: user.id, name: user.name, exp: Date.now() + 3600 };
return jwt.sign(payload, SECRET_KEY);
}
// 应用端验证中间件
function authMiddleware(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
try {
const decoded = jwt.verify(token, SECRET_KEY);
req.user = decoded;
next();
} catch (err) {
res.status(401).json({ error: 'invalid_token' });
}
}