概念:单点登录(Single Sign-On, SSO)主要是在多个系统、多个浏览器或多个标签页之间共享登录状态,保证用户只需登录一次,就能访问多个关联应用,而不需要重复登录。
💡 方案分类
1. 前端级别 SSO(仅适用于同源)
适用于:同一域名下的多个系统或标签页
| 方案 | 适用范围 | 共享方式 | 缺点 | 
|---|---|---|---|
localStorage | 同浏览器、同源 | localStorage 共享 token | 不支持跨浏览器或隐身模式 | 
sessionStorage | 仅当前标签页 | sessionStorage | 关闭标签页即失效 | 
cookie | 同域、所有浏览器 | 服务器 Set-Cookie | 不能跨域,容量限制 | 
BroadcastChannel | 同浏览器、同域 | postMessage 事件广播 | 仅适用于同浏览器 | 
2. 前后端结合 SSO(适用于跨域)
适用于:多个子系统,支持不同域名共享登录
| 方案 | 适用范围 | 共享方式 | 适合场景 | 
|---|---|---|---|
| OAuth 2.0 + JWT | 跨域、多端 | 通过授权服务器获取 token | 第三方登录(微信、GitHub) | 
| CAS (Central Authentication Service) | 内部系统 | CAS 服务器管理登录态 | 企业内网统一认证 | 
SSO + Cookie(SameSite=None + CORS) | 跨子域 | 主域 *.example.com 共享 cookie | 适用于 SaaS 平台 | 
| SSO + Redis + Session | 跨域 | token 存 Redis,前端查询 | 高并发业务 | 
🔹 方案 1:前端 localStorage + BroadcastChannel(适用于同域)
 
适用于:同一浏览器的多个标签页
 💡 实现思路:
-  
登录时,将
token存入localStorage并通知其他标签页 -  
新标签页打开时,自动获取
localStorage的token -  
监听
localStorage变化,保证token实时同步 
// 登录时设置 token
localStorage.setItem('token', 'your-token-value')// 监听 token 变化,保证新打开的页面能同步
window.addEventListener('storage', (event) => {if (event.key === 'token') {console.log('新 token:', event.newValue)}
})
 
✅ 优点:
-  
实现简单
 -  
无需后端支持
 -  
适用于同一浏览器、同一域名下的多个系统
 
❌ 缺点:
-  
不能跨浏览器、跨设备共享
 -  
不能跨域名(如
a.com无法共享b.com的token) 
🔹 方案 2:SSO + Cookie 共享(适用于跨子域)
适用于:跨子域(如 admin.example.com 和 user.example.com)
 💡 实现思路:
-  
后端设置
cookie,作用域为*.example.com -  
前端所有子系统 访问
cookie共享登录状态 -  
跨域设置
SameSite=None; Secure 
后端(Node.js 示例)
res.cookie('token', 'your-token', {domain: '.example.com', // 设置作用域path: '/',httpOnly: true,secure: true,sameSite: 'None' // 允许跨域
})
 
前端
fetch('https://auth.example.com/check-login', {credentials: 'include' // 允许跨域携带 Cookie
}).then(res => res.json()).then(data => {console.log('登录状态:', data)})
 
✅ 优点:
-  
支持多个子域共享登录
 -  
安全性较高
 -  
用户体验好
 
❌ 缺点:
-  
不能跨主域(如
example.com不能共享other.com) -  
需要 HTTPS
 -  
浏览器
SameSite限制较多 
🔹 方案 3:OAuth 2.0 + JWT(适用于跨域、第三方登录)
适用于:多端、第三方应用、社交登录(如 Google、GitHub、微信)
 💡 实现思路:
-  
用户在 SSO 服务器 登录,返回
token -  
其他系统使用
token请求 SSO,获取用户信息 -  
通过
OAuth标准协议授权 
前端 OAuth 登录
window.location.href = `https://sso.example.com/oauth/authorize?client_id=your-client-id&redirect_uri=${encodeURIComponent(window.location.href)}`
 
后端验证 token
 
app.get('/auth/user', async (req, res) => {const token = req.headers.authorization?.split(' ')[1]const user = verifyToken(token) // 解析 JWTres.json(user)
})
 
 
✅ 优点:
-  
支持跨域、跨设备
 -  
可用于第三方应用
 -  
安全性高
 
❌ 缺点:
-  
需要后端支持
OAuth 2.0 -  
token需要存cookie或localStorage 
🔹 方案 4:SSO + Redis + Session(适用于企业系统)
适用于:企业级 SSO(如钉钉、企业微信)
 💡 实现思路:
-  
用户登录后,后端将
session存入 Redis -  
不同系统请求 SSO,校验
session是否有效 -  
用户登出时,删除 Redis
session 
后端
const sessionStore = new Redis() // 连接 Redisapp.post('/login', (req, res) => {const token = generateToken(req.body.user)sessionStore.set(token, JSON.stringify(req.body.user), 'EX', 3600) // 存入 Redisres.json({ token })
})app.get('/check-session', async (req, res) => {const token = req.headers.authorization?.split(' ')[1]const session = await sessionStore.get(token)if (session) {res.json(JSON.parse(session))} else {res.status(401).json({ message: '未登录' })}
})
 
✅ 优点:
-  
可以跨域、跨浏览器共享登录
 -  
适用于大规模企业级系统
 -  
支持 SSO 统一管理
 
❌ 缺点:
-  
需要后端支持 Redis
 -  
实现较复杂
 
📌 方案对比
| 方案 | 适用范围 | 共享方式 | 安全性 | 适合场景 | 
|---|---|---|---|---|
localStorage | 同浏览器 | localStorage | 低 | 前端应用 | 
BroadcastChannel | 同浏览器 | postMessage | 低 | 单页面应用 | 
Cookie + SameSite | 跨子域 | cookie | 中 | 内部 SaaS 系统 | 
OAuth 2.0 + JWT | 跨域、第三方 | token | 高 | 公共平台 | 
SSO + Redis | 跨系统、跨浏览器 | session | 高 | 企业 SSO | 
🎯 最佳实践
-  
小型前端应用(SPA) ➝
localStorage + BroadcastChannel -  
企业 SaaS(跨子域) ➝
Cookie + SameSite=None -  
第三方登录(跨域) ➝
OAuth 2.0 + JWT -  
企业级 SSO(跨浏览器、多系统) ➝
Redis + Session 
推荐组合:
 ✅ SSO + OAuth 2.0 + Redis + JWT,适用于高安全性、多端登录