Node.js SSO 单点登录
SSO(Single Sign-On)允许用户一次登录,访问多个应用,无需每个系统单独登录。
核心优势
| 优势 | 说明 |
|---|---|
| 用户友好 | 一次登录,多系统免登 |
| 安全性 | 集中认证,减少密码泄露风险 |
| 简化管理 | 无需每个应用单独管理用户 |
设计思路
┌──────────────────────────────────────┐
│ SSO 认证中心 (center) │
│ 统一登录 / 验证 token / 颁发 token │
└──────┬───────────────┬───────────────┘
│ │
┌────▼────┐ ┌────▼────┐
│ 应用 A │ │ 应用 B │
│ appId_A │ │ appId_B │
│ secret_A│ │ secret_B│
└─────────┘ └─────────┘每个应用有独立的 appId + secret + 回调 URL。
登录流程
1. 用户访问应用 A(未登录)
→ 重定向到 SSO 认证中心,携带 appId
2. SSO 中心检查用户是否已登录
未登录:
→ 显示登录页面 → 输入用户名密码 → 验证
→ 生成全局 session / token
已登录:
→ 直接用已存在的 session 生成新 token
3. SSO 中心生成 token(用 secret 签名)
→ 重定向回应用 A 的回调 URL + token
4. 应用 A 收到 token → 用 secret 验证 → 建立本地会话
5. 用户访问应用 B
→ 重定向 SSO → 已登录 → 直接返回 token → 免登录Express 简化实现
SSO 认证中心
js
// 登录页
app.get('/login', (req, res) => {
res.render('login', { appId: req.query.appId })
})
// 验证登录
app.post('/login', (req, res) => {
const { username, password, appId } = req.body
// 验证用户名密码...
const token = jwt.sign({ userId, appId }, secret, { expiresIn: '7d' })
// 重定向回应用
res.redirect(`${getCallbackUrl(appId)}?token=${token}`)
})应用接入
js
app.get('/callback', (req, res) => {
const token = req.query.token
const decoded = jwt.verify(token, appSecret)
// 建立本地会话...
res.redirect('/home')
})关键点
- 全局 Session 存在 SSO 中心(Redis/JWT)
- 每个应用独立
appId+secret,token 权限不同 - 重定向回应用时携带 token