js实现单点登录
单点登录(SSO)的基本原理
单点登录(SSO)是一种身份验证机制,允许用户通过一次登录访问多个相互信任的应用系统。核心原理是通过统一的认证中心(如独立的SSO服务器)管理用户身份,其他系统通过令牌或票据验证用户身份。
基于Token的SSO实现方案
前端实现关键步骤
-
登录页面跳转
用户访问应用A时,前端检查本地是否存在有效Token(如Cookie或LocalStorage)。若无Token,跳转至SSO登录页:if (!localStorage.getItem('sso_token')) { window.location.href = 'https://sso-server.com/login?redirect=' + encodeURIComponent(window.location.href); } -
Token验证与存储
SSO登录成功后,前端通过URL参数或PostMessage接收Token,并存储:// 从URL解析Token(SSO回调时) const params = new URLSearchParams(window.location.search); const token = params.get('token'); if (token) { localStorage.setItem('sso_token', token); } -
跨域Token共享
对于子域名不同的系统,通过设置Cookie的Domain属性实现共享:document.cookie = `sso_token=${token}; domain=.example.com; path=/; secure`;
后端验证逻辑示例
-
SSO服务器生成Token
使用JWT生成包含用户信息的Token:const jwt = require('jsonwebtoken'); const token = jwt.sign({ userId: '123' }, 'SECRET_KEY', { expiresIn: '1h' }); -
应用系统验证Token
各子系统收到请求后,向SSO服务器验证Token有效性:app.get('/api/data', (req, res) => { const token = req.headers.authorization?.split(' ')[1]; jwt.verify(token, 'SECRET_KEY', (err, decoded) => { if (err) return res.status(401).send('Invalid token'); // 允许访问资源 }); });
跨域解决方案
-
CORS配置
SSO服务器需设置允许跨域的响应头:res.setHeader('Access-Control-Allow-Origin', 'https://app.example.com'); res.setHeader('Access-Control-Allow-Credentials', 'true'); -
PostMessage通信
适用于完全不同的域名,通过window.postMessage传递Token:// SSO登录页 window.opener.postMessage({ token: 'xyz' }, 'https://app.example.com'); // 应用页面 window.addEventListener('message', (event) => { if (event.origin === 'https://sso-server.com') { localStorage.setItem('sso_token', event.data.token); } });
安全增强措施
-
Token过期与刷新
设置较短的Token有效期,并提供刷新机制:// 检查Token过期时间 const decoded = jwt.decode(token); if (decoded.exp < Date.now() / 1000) { fetch('/refresh-token', { method: 'POST' }); } -
CSRF防护
对敏感操作添加CSRF Token验证:// 生成CSRF Token并存入Session const csrfToken = crypto.randomBytes(32).toString('hex'); req.session.csrfToken = csrfToken; res.json({ csrfToken });
完整流程示例
- 用户访问AppA,未登录则跳转至SSO登录页。
- 用户在SSO页完成认证,SSO生成Token并重定向回AppA。
- AppA存储Token,后续请求携带Token访问资源。
- 用户访问AppB时,AppB通过检查SSO的Token实现自动登录。
注意:生产环境需使用HTTPS、合理设置Token有效期,并考虑引入OAuth2.0等标准协议增强安全性。







