单点登录 (SSO)实现方案详解
一、核心原理
目标:用户登录系统A后,访问系统B无需重复登录
关键:建立信任关系 + 统一认证中心
二、主流实现方案
1. 基于 Cookie 的SSO(经典方案)
适用场景:同主域名下的子系统(如a.com和b.com)
实现步骤:
-
统一认证中心部署在
auth.com -
各子系统设置Cookie域为
.com(共享顶级域) -
登录后认证中心种Cookie,各子系统读取该Cookie
代码示例:
// 认证中心设置跨域Cookie
response.setHeader('Set-Cookie', 'sso_token=xxxx; Domain=.com; Path=/; HttpOnly');
2. OAuth2.0 / OpenID Connect (现代方案)
适用场景:跨域/第三方系统集成
角色:
-
授权服务器(如Keycloak)
-
资源服务器(业务系统)
-
客户端(Web/移动端)
流程:
3. JWT + 中央认证(无状态方案)
特点:
-
认证中心颁发JWT
-
子系统自行验证JWT签名
-
无需每次请求认证中心
Token结构:
{
"alg": "HS256",
"typ": "JWT",
"user": "admin",
"exp": 1735689600,
"iss": "auth.center"
}
三、具体实现步骤(以方案2为例)
1. 认证中心搭建
// 登录接口
app.post('/login', (req, res) => {
const { user, pass } = req.body;
if (checkAuth(user, pass)) {
const token = generateJWT(user);
res.cookie('sso_token', token, { domain: '.company.com' });
res.json({ token });
}
});
2. 子系统校验
// 拦截器检查登录状态
function checkAuth(req, res, next) {
const token = req.cookies.sso_token || req.headers.authorization;
if (verifyJWT(token)) {
next(); // 已登录
} else {
redirectToAuthCenter(req.url); // 跳转认证
}
}
3. 跨域处理(关键!)
# Nginx配置允许跨域
add_header 'Access-Control-Allow-Origin' 'https://auth.center';
add_header 'Access-Control-Allow-Credentials' 'true';
四、安全增强措施
-
Token安全:
-
使用HttpOnly + Secure Cookie
-
JWT设置短期有效期(如30分钟)
-
敏感操作需二次认证
-
-
防 CSRF:
-
重要接口校验Referer
-
添加CSRF Token
-
-
监控:
-
记录异常登录行为
-
多设备登录提醒
-
五、常见问题解决方案
Q1:跨顶级域名怎么办?(如a.com和b.net)
-
方案:
-
认证中心页面内嵌隐藏iframe,通过postMessage传递Token
-
使用OAuth2.0的
token模式直接返回JWT
-
Q2:移动端如何适配?
-
方案:
-
App使用系统浏览器完成认证(Chrome Custom Tabs)
-
通过Deep Link回传Token到原生应用
-
Q3:用户退出如何全局登出?
-
方案:
-
// 认证中心退出接口 app.post('/logout', (req, res) => { invalidateToken(req.cookies.sso_token); res.clearCookie('sso_token'); notifyAllSystems(req.userId); // 通知各子系统清理会话 });
-
六、面试回答技巧
错误回答:
"我们用Cookie实现了SSO"
专业回答:
"在电商平台项目中,我设计了基于OIDC的SSO方案:
-
架构选择:因涉及
mall.com和erp.com跨域,采用中央认证服务 -
关键实现:
- 认证中心用JWT签发短期Token
- 子系统通过
/userinfo端点校验有效性
-
安全措施:
- 令牌绑定设备指纹防盗用
- 敏感操作强制重新认证
上线后用户登录耗时减少70%,客服咨询量下降40%"