文章目錄
- 多 Web 端子系統共享會話:原理與實踐
- 同主域名共享方案:Cookie + Session 集中存儲
- 原理
- 實現方案
- 1. Cookie 設置要點
- 2. 集中式 Session 管理
- 3. 單點登出機制
- 跨主域方案:SSO 認證中心(推薦)
- 原理
- 標準模型
- 登錄流程
- 優勢
- 安全要點
- 臨時場景:URL Token 傳遞(不推薦長期使用)
- 實現示例
- 注意事項
- 選型建議
- 結語
多 Web 端子系統共享會話:原理與實踐
- 在多 Web 端子系統架構中(例如:app.example.com、admin.example.com、shop.example.com),用户通常期望一次登錄即可在所有系統間無感跳轉。
- 實現這一目標的關鍵在於:
1、共享用户身份憑證(Session/Token)
2、集中管理登錄狀態與過期機制
3、保證安全性與一致性
- 本文基於同主域名、非同主域名兩種方案分析常見的解決方案。
同主域名共享方案:Cookie + Session 集中存儲
原理
- 在同主域名(如 example.com)下,可以通過設置 Domain=.example.com 的 Cookie,讓所有子域共享同一會話標識符(如 SESSIONID)。後端通過集中式會話存儲(如 Redis)統一管理會話數據,實現登錄態的共享與續期。
實現方案
1. Cookie 設置要點
Domain=.example.com→ 允許子域共享;Path=/→ 全路徑有效;HttpOnly=true→ 防止 JS 讀取;Secure=true→ 僅在 HTTPS 傳輸;SameSite=None→ 跨子域請求時必須。
示例(Spring Boot):
ResponseCookie cookie = ResponseCookie.from("SESSIONID", sessionId)
.domain(".example.com")
.path("/")
.httpOnly(true)
.secure(true)
.sameSite("None")
.maxAge(Duration.ofHours(2))
.build();
response.setHeader(HttpHeaders.SET_COOKIE, cookie.toString());
2. 集中式 Session 管理
- 所有後端服務共享一個 Redis 作為會話存儲:
key: session:abc123
val: { userId: 1001, roles: [...], expiresAt: 173.. }
3. 單點登出機制
後端提供登出接口:
- 刪除 Redis 中的會話數據;
- 如需廣播登出,可通過消息隊列(Kafka / Redis PubSub)通知其他子系統同步。
跨主域方案:SSO 認證中心(推薦)
原理
跨域時 Cookie 無法共享,需通過 統一認證中心(SSO) 管理登錄態。認證中心保存用户主會話,並在各前端域請求登錄時發放臨時 Token(如 OAuth2 的授權碼),由各前端後端交換 Token 並建立本域的會話。
標準模型
- 基於
OAuth2 + OpenID Connect (OIDC); - 支持授權碼 + PKCE 流程;
- 認證中心維護主 Session;
- 各前端服務通過 Token Exchange 獲取訪問令牌;
- 支持單點登錄 / 單點登出。
登錄流程
- 用户訪問
appA.com→ 未登錄 → 重定向至auth.example.com; - 登錄成功 → Auth Server 發放授權碼
code; appA.com後端通過code換取 Token;- 後端為
appA.com設置本域 HttpOnly Cookie; - 用户訪問
appB.net時,Auth Server 檢測已有主 Session,直接簽發 Token(無感登錄)。
核心代碼(Java 偽示例):
String code = request.getParameter("code");
TokenResponse token = oauthClient.exchangeCodeForToken(code);
String sessionId = createLocalSession(token);
setCookie(response, "SESSIONID", sessionId, domain = "appB.net");
優勢
- 用户無感登錄,支持單點登出;
- Token 標準化,易擴展第三方登錄;
- 權限管理集中統一。
安全要點
- 使用短期 Access Token + 長期 Refresh Token;
- Token 過期、撤銷、黑名單機制完善。
臨時場景:URL Token 傳遞(不推薦長期使用)
- 用於跨域跳轉、郵件免登錄、短鏈分享等臨時需求。
實現示例
appA.com生成短期 Token 並跳轉:
https://appB.net/accept?token=eyJhbGciOi...
appB.net校驗 Token → 生成本地 Session → 重定向去除參數。
偽代碼:
app.get('/accept', async (req, res) => {
const token = req.query.token;
const payload = verifyOneTimeToken(token);
if (!payload) return res.status(401).send('invalid');
const sessionId = await createLocalSession(payload.userId);
res.cookie('SESSIONID', sessionId, { httpOnly: true, secure: true });
res.redirect('/');
});
注意事項
- Token 必須短期有效(30 秒–5 分鐘);
- 僅服務端驗證使用,前端不可存儲;
- 校驗後立刻失效(防重放);
- 避免通過 Referer 泄露。
選型建議
|
場景
|
推薦方案
|
特點
|
|
同主域名
|
Cookie + 集中式 Session(Redis)
|
簡單高效,穩定可靠
|
|
跨主域
|
SSO(OAuth2/OIDC)
|
標準方案,無感體驗
|
|
臨時跨域
|
URL Token
|
短期可用,風險高
|
結語
- 同主域名:首選
Cookie + Redis Session 共享,簡單高效; - 跨主域:推薦
SSO 統一認證中心(OAuth2/OIDC),支持擴展與審計; - 臨時跳轉:可使用
URL Token,但需嚴格時效與安全控制。