文章目錄

  • 多 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. 單點登出機制

後端提供登出接口:

  1. 刪除 Redis 中的會話數據;
  2. 如需廣播登出,可通過消息隊列(Kafka / Redis PubSub)通知其他子系統同步。

跨主域方案:SSO 認證中心(推薦)

原理

跨域時 Cookie 無法共享,需通過 統一認證中心(SSO) 管理登錄態。認證中心保存用户主會話,並在各前端域請求登錄時發放臨時 Token(如 OAuth2 的授權碼),由各前端後端交換 Token 並建立本域的會話。

標準模型

  • 基於 OAuth2 + OpenID Connect (OIDC)
  • 支持授權碼 + PKCE 流程;
  • 認證中心維護主 Session;
  • 各前端服務通過 Token Exchange 獲取訪問令牌;
  • 支持單點登錄 / 單點登出。

登錄流程

  1. 用户訪問 appA.com → 未登錄 → 重定向至 auth.example.com
  2. 登錄成功 → Auth Server 發放授權碼 code
  3. appA.com 後端通過 code 換取 Token;
  4. 後端為 appA.com 設置本域 HttpOnly Cookie;
  5. 用户訪問 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 傳遞(不推薦長期使用)

  • 用於跨域跳轉、郵件免登錄、短鏈分享等臨時需求。

實現示例

  1. appA.com 生成短期 Token 並跳轉:
https://appB.net/accept?token=eyJhbGciOi...
  1. 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,但需嚴格時效與安全控制。