什么是单点登录,如何实现

核心概念

不同域名下的多个子系统共享登录状态

关键原理

### 🔄postMessage + LocalStorage

这种方式的实现原理是登录主系统后,将token通过postMessage发送给子系统,子系统进行message的监听

js 复制代码
	// 主系统登录成功逻辑  
	const token = "xxxx";  
	const domains = ["https://sub1.com", "https://sub2.com"];  
	domains.forEach(domain => {  
	  const iframe = document.createElement("iframe");  
	  iframe.style.display = "none";  
	  iframe.src = `${domain}/sso-sync.html`;  
	  document.body.appendChild(iframe);  
	  iframe.onload = () => iframe.contentWindow.postMessage(token, domain);  
	});
	//子系统sso-sync.html页面
	<!-- sub1.com/sso-sync.html -->  
	<script>  
	  window.addEventListener("message", e => {  
	    if (e.origin === "https://main.com") localStorage.setItem("token", e.data);  
	  });  
	</script>

该种方式,有一个我一直没理解的就是,需要在主系统的iframe中打开子系统的一个专门的页面用来接收主系统的postMessage,总感觉不是很顺

🔒 ​反向代理统一入口方案

通过nginx来配置代理,是一个很巧妙的方式,打开逻辑就是将不同域名执行同一个域名的不同的子路径,在浏览器端仍然是一个路径下,实现登录状态的共享

nginx 复制代码
	server {
	  listen 80;
	  server_name gateway.com; # 统一入口域名
	  location /app1 { proxy_pass http://app1.com; }
	  location /app2 { proxy_pass http://app2.com; }
	}
  • 所有系统访问入口为 gateway.com/app1gateway.com/app2,浏览器视为同源。
  • 系统间跳转使用相对路径(如 window.location.href = '/app2/home'),避免跨域检测

🧩 ​CORS + 集中式认证中心方案

适用于独立域名系统且需精细控制跨域权限的场景。具体的实现就是将登录的逻辑交给一个独立的域名下-认证中心,所有的子系统在未登录的情况下,重定向到认证中心进行登录,并在登录后跳回原子系统,并携带token 在后续的子系统登录时采用同样逻辑,跳转到认证中心,因为认证中心已经登录过,所以可以直接回传回第二个子系统,实现一次登录,不同系统的状态共享

  1. 认证中心设计
    • 独立部署于 auth-center.com,提供登录页和令牌签发接口。
    • 响应头配置:
http 复制代码
	Access-Control-Allow-Origin: https://app1.com
	Access-Control-Allow-Credentials: true
  1. 子系统登录跳转
    • 未登录用户访问 app1.com时,重定向至:
js 复制代码
	window.location.href = 'https://auth-center.com/login?redirect_uri=' + encodeURIComponent('https://app1.com/callback');
  1. 令牌传递与验证
    • 认证中心回调 app1.com/callback?token=xxxx,前端存储令牌至内存或 SessionStorage
    • 切换至 app2.com时,重复上述流程,认证中心通过 Cookie自动识别已登录用户,直接签发令牌

图表

🔄postMessage + LocalStorage

graph TD A[用户登录主系统] --> B[主系统生成Token] B --> C[创建隐藏iframe加载子系统页面] C --> D[iframe加载完成后发送postMessage] D --> E[子系统监听message事件] E --> F[接收Token存入LocalStorage] F --> G[子系统建立本地会话]

​CORS + 集中式认证中心方案

graph LR A[用户访问子系统A] --> B{本地有Token?} B -->|无| C[重定向至认证中心] B -->|有| D[验证Token有效性] C --> E[用户在认证中心登录] E --> F[认证中心生成Token] F --> G[重定向回子系统A并附带Token] G --> H[子系统A验证Token] H --> I[建立本地会话] I --> J[用户访问子系统B] J --> K{本地有Token?} K -->|无| C K -->|有| D
相关推荐
我命由我123451 小时前
React - 类组件 setState 的 2 种写法、LazyLoad、useState
前端·javascript·react.js·html·ecmascript·html5·js
自由生长20242 小时前
IndexedDB的观察
前端
IT_陈寒2 小时前
Vite热更新坑了我三天,原来配置要这么写
前端·人工智能·后端
斯班奇的好朋友阿法法2 小时前
离线ollama导入Qwen3.5-9B.Q8_0.gguf模型
开发语言·前端·javascript
掘金一周2 小时前
每月固定续订,但是token根本不够用,掘友们有无算力焦虑啊 | 沸点周刊 4.2
前端·aigc·openai
小村儿2 小时前
连载加餐01-claude code 源码泄漏 ---一起吃透 Claude Code,告别 AI coding 迷茫
前端·后端·ai编程
莫物3 小时前
vue过滤表格数据导致的索引错乱问题
前端·javascript·vue.js
竹林8183 小时前
从监听失败到实时更新:我在NFT铸造项目中搞定合约事件监听的全过程
前端·javascript
光影少年3 小时前
手写防抖和节流
前端·javascript·前端框架
笨笨狗吞噬者3 小时前
uni-app 编译小程序原生组件时疑似丢属性,可以给官方提 PR 了
前端·微信小程序·uni-app