4. 单点登录(SSO)

🔐 一次登录,全网通行 —— 工作原理 · 实现方式 · 常见问题

4.1 SSO 工作原理

单点登录(Single Sign-On)允许用户使用一组凭据登录多个独立系统。核心是建立一个中央认证服务(CAS),所有应用信任该服务颁发的身份票据。

用户 应用 A 中央认证 CAS / IdP 应用 B · 应用 C

流程简述 用户访问应用A → 重定向至CAS登录 → CAS验证凭据 → 下发全局票据(Ticket) → 用户携带票据访问应用B/C,无需再次输入密码。

4.2 SSO 实现方式

🔹 基于 Cookie 的 SSO

在同一个父域下(如 .example.com),认证中心设置全局 Cookie,各子域共享该 Cookie 实现登录态传递。

auth.example.com app1.example.com app2.example.com 🍪 全局 Cookie (domain=.example.com) 共享会话 读取 Cookie 读取 Cookie

优点:实现简单,适合同域架构。 缺点:跨域无法直接共享 Cookie,安全性依赖 Cookie 属性。

🔸 基于 Token 的 SSO

认证中心颁发签名的 Token(如 JWT),应用通过验证 Token 的签名和声明来确认身份,不依赖 Cookie 域。

IdP App X App Y JWT JWT 验证签名 + 声明 验证签名 + 声明 Token 无状态,跨域友好

优点:跨域、跨平台,无状态,适合微服务。 缺点:Token 泄露风险,需配合刷新机制。

特性基于 Cookie基于 Token
跨域支持受限(需父域)天然支持
状态有状态(服务端会话)无状态(自包含)
安全风险CSRF、Cookie 劫持Token 泄露、重放
典型协议CAS (传统)OIDC / JWT

4.3 SSO 常见问题

⚠️ 会话管理

IdP 会话 App A 会话 App B 会话 ⏱️ 超时不同步 登出广播 SLO 回调

🌐 跨域问题

域A 域B SSO 网关 Cookie ❌ Token ✅ 代理 / 网关

📄 基于 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' });
    }
}