聊一下单点登录如何给不同域名种 cookie

2025-05-03
JavaScript
41

背景

一个规模大点的公司大概率会有很多子系统,每个子系统都是属于公司的。用户在一个系统登录之后,登录状态会同步到所有的系统,没必要再在另一个系统登录一遍。

要实现这个能力,一个很重要的手段就是将当前网站的登录 cookie 信息同步到另一个网站下。但是受浏览器同源策略的限制,无法直接给非同源网站设置 cookie。

本文将通过几种方案,实现不同网站之间互相设置 cookie

cookie

主域名

如果两个网站是同一个主域名,可以将cookie设置到 主域名下,之后,所有二级域名可以共享

比如:www.baidu.com,tongji.baidu.com两个网站,可以将 cookie 设置到 .baidu.com 这个主域下。

// express 代码,设置cookie
res.cookie('token', '$$$$$$$$$', {
    domain: '.baidu.com', // 注意前面的点号
    maxAge: 86400000,     // 1天有效期
    httpOnly: true,       // 防止 XSS 攻击
    secure: true,         // 只在 HTTPS 下传输
    sameSite: 'lax'       // 防止 CSRF 攻击
});

图片

跨主域的话,可以让另一个域名实现一个设置 cookie 的接口,利用浏览器可以访问外部资源的特性,通过访问这个接口,达到设置 cookie 的能力。

const img = new Image()

img.src = 'https://toutiao.com/setToken?token=$$$$'

iframe

利用iframe通信,实现两个域名之后的信息传递

<!-- 主网站 baidu.com -->
<iframe id="ssoFrame" src="https://aliyun.com/sso" style="display:none"></iframe>

<script>
  // 监听来自 iframe 的消息
  window.addEventListener('message', (event) => {
    if (event.origin !== 'https://aliyun.com') return;

    if (event.data.type === 'sso_token') {
      // 设置本地 Cookie
      document.cookie = `auth_token=${event.data.token}; path=/; secure`;
    }
  });

  // 用户登录后通知 iframe
  function notifyLogin(token) {
    const frame = document.getElementById('ssoFrame');
    frame.contentWindow.postMessage({
      type: 'sso_notify',
      token: token
    }, 'https://aliyun.com');
  }
</script>

结语

要实现跨系统的单点登录(SSO),主要有三种方案:

  1. 同主域名共享 Cookie:适用于相同主域名的子系统(如 a.baidu.comb.baidu.com),直接设置主域名 Cookie 即可共享。

  2. 跨域接口设置 Cookie:不同域名(如 baidu.comaliyun.com)可通过动态请求目标域名的接口(如 <img>fetch)触发 Cookie 写入。

  3. iframe 通信:利用 postMessage 实现跨域通信,安全传递 Token 并写入 Cookie。

选择方案时,优先考虑同主域名共享,跨域场景可结合接口调用或 iframe 通信实现。

原文地址:https://webfem.com/post/share-cookie,转载请注明出处