Skip to content

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