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

核心概念

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

关键原理

### 🔄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
相关推荐
智算菩萨14 分钟前
实战:高级中文自然语言处理系统的Python设计与实现
前端·javascript·easyui
远山无期36 分钟前
解决Tailwind任意值滥用:规范化CSS开发体验
前端·css·eslint
用户542778485154044 分钟前
Vue 3 中开发高阶组件(HOC)与 Renderless 组件
前端
HIT_Weston1 小时前
67、【Ubuntu】【Hugo】搭建私人博客(一)
前端·ubuntu·hugo
阿里巴啦1 小时前
用React+Three.js 做 3D Web版搭建三维交互场景:模型的可视化摆放与轻量交互
前端·react·three.js·模型可视化·web三维·web三维交互场景
Liu.7741 小时前
vue3组件之间传输数据
前端·javascript·vue.js
|晴 天|1 小时前
前端闭包:从概念到实战,解锁JavaScript高级技能
开发语言·前端·javascript
开发者小天1 小时前
react的拖拽组件库dnd-kit
前端·react.js·前端框架
用户4445543654262 小时前
在Android开发中阅读源码的指导思路
前端
用户54277848515402 小时前
ESM 模块(ECMAScript Module)详解
前端