域登錄態(tài)分享(類sso)
遇到一個問題,在同一主域下的多個子域之間共享登錄狀態(tài)的需求。例如:
main.example.com主站learn.example.com學習中心
希望在任意子域登錄后,其他子域也能自動識別登錄狀態(tài),包括登出同步。
Cookie 跨子域共享
瀏覽器安全策略允許 Cookie 在同一主域下共享,只需設置父域(.example.com 指的是包括 example.com 及子域名下都可以共用 cookie,單一指定直接放上域名即可):
| 請求來源 | Cookie 域 | 是否生效 |
|---|---|---|
main.example.com |
.example.com |
? |
learn.example.com |
.example.com |
? |
示例:
Set-Cookie: sid=xxxxx; Domain=.example.com; Path=/; Secure; HttpOnly; SameSite=None
后端通過 Set-Cookie 響應頭設置 Cookie,使其在所有子域生效。
自定義方案:集中式 Session(共享 sid 模型)
方案核心
- 所有系統(tǒng)在后端共用一個 Session 中心(存儲登錄 sid 與用戶信息映射)。
- 用戶在任一子域(如
main.example.com)登錄后,后端生成唯一 sid 并通過Set-Cookie寫入.example.com域。 - 其他子域(如
learn.example.com)訪問時,會自動攜帶同一 Cookie 中的 sid。 - 各子域后端通過 Session 服務驗證 sid 是否有效。
- 若 sid 存在且有效,則返回用戶信息或簽發(fā) token。
- 退出登錄時刪除 sid,實現(xiàn)所有子域同步登出。
登錄與驗證流程
1. 用戶登錄(main.example.com)
// 前端僅調(diào)用登錄接口
await fetch('https://api.main.example.com/login', {
method: 'POST',
body: JSON.stringify({ username, password }),
credentials: 'include'
});
后端示例(Node.js):
app.post('/login', (req, res) => {
const { username, password } = req.body;
const user = authenticate(username, password);
if (user) {
const sid = generateSid();
sessionStore.set(sid, user);
res.cookie('sid', sid, {
domain: '.example.com',
httpOnly: true,
secure: true,
sameSite: 'none',
path: '/',
});
res.json({ success: true });
} else {
res.status(401).json({ success: false });
}
});
2. 子域驗證登錄狀態(tài)(learn.example.com)
請求示例:
await fetch('https://session.example.com/api/validate', {
credentials: 'include'
});
后端驗證:
app.get('/api/validate', (req, res) => {
const sid = req.cookies.sid;
const session = sessionStore.get(sid);
if (session) {
res.json({ valid: true, user: session.user });
} else {
res.json({ valid: false });
}
});
3. 登出同步
所有子域使用同一域的 Cookie:
app.post('/logout', (req, res) => {
const sid = req.cookies.sid;
sessionStore.delete(sid);
res.clearCookie('sid', { domain: '.example.com', path: '/' });
res.json({ success: true });
});
與標準 SSO 的區(qū)別對比
| 特性 | 自定義集中 Session 模型 | 標準化 SSO(OAuth2 / OIDC) |
|---|---|---|
| 登錄管理中心 | ? 有 Session 中心 | ? 獨立 IdP(認證中心) |
| 登錄憑證形式 | sid(后端 Session) | Access Token / ID Token(標準) |
| 協(xié)議 | ? 自定義 | ? OAuth2 / OpenID Connect / SAML |
| 安全性 | ?? 依賴服務端實現(xiàn) | ? 采用業(yè)界安全標準 |
| 跨域處理 | 通過共享 Cookie | 統(tǒng)一跳轉 + 授權碼機制 |
| 登出同步 | Cookie 統(tǒng)一清除 | IdP 通知各客戶端登出 |
| 擴展性 | 內(nèi)部系統(tǒng)適用 | 可對外開放第三方登錄 |
方案優(yōu)缺點
優(yōu)點
- 后端集中控制登錄狀態(tài),安全性高。
- 實現(xiàn)簡單,適合同一主域下多子系統(tǒng)。
- 通過
Set-Cookie跨子域自動共享,無需前端參與。
缺點
- 無標準協(xié)議,不適合開放平臺。
- 若 Session 存儲異常,影響所有子系統(tǒng)。
- 無法跨不同主域(如
.example.com與.example.org)。
演進方向
若未來需要:
- 對接外部系統(tǒng)或移動端;
- 支持 OAuth2 授權流程;
- 集成權限管理;
應演進為 標準化 SSO 架構:
[main.example.com] --> [auth.example.com] <-- [learn.example.com]
│
└--> Issue JWT / Refresh Token
總結
| 場景 | 推薦方案 |
|---|---|
| 同一主域下多子域共享登錄 | ? 集中 Session 模型 |
| 不同主域間登錄共享 | ? 標準 SSO(OAuth2/OIDC) |
| 內(nèi)部系統(tǒng)快速集成 | ? 自建 Session 驗證機制 |
| 長期擴展性 | ?? 升級為標準認證中心 |
總結:這個方案是參考 SSO 實現(xiàn)(輕量化內(nèi)部集中式 Session 模型),主要是在同一主域多子域場景下,也可以使用 nginx 代理指向不同文件夾,有興趣可以自行了解。后面會出一個 sso 方案,為 OAuth2 / OpenID Connect 架構。有問題大家提出討論會進行更正!

浙公網(wǎng)安備 33010602011771號