单点击登录sso实现

一、单点登录(SSO)是什么?

核心定义

单点登录(Single Sign-On,SSO)是一种身份认证解决方案,允许用户通过一次登录访问多个相互信任的应用系统。其核心逻辑是统一认证中心分布式会话管理,避免用户重复输入凭证,提升跨系统访问效率。

技术原理
  1. 独立认证中心(Passport)
    所有子系统的登录请求均由认证中心处理,子系统本身不存储用户凭证。认证中心负责验证用户身份,并颁发全局唯一的令牌(Token)或会话标识(Session ID)
  2. 令牌传递与会话共享
    • 认证中心登录成功后,生成令牌并通过安全方式(如 Cookie、Header)传递给子系统。
    • 子系统通过令牌向认证中心验证用户身份,验证通过后建立局部会话(存储用户权限等信息),实现免密访问。
  3. 跨系统会话一致性
    • 全局会话:用户与认证中心的会话,标识用户整体登录状态。
    • 局部会话:用户与单个子系统的会话,依赖全局会话存在。
    • 约束关系:全局会话销毁时,所有局部会话需同步销毁;局部会话存在时,全局会话必然存在。
经典案例:电商平台跨应用登录

React 电商中台系统 为例:

  • 主站(main.com)使用 React 开发,管理后台(admin.com)使用 Vue3 开发,两者域名不同。

  • 用户在主站登录后,认证中心(

    sso.com
    

    )生成 Token,并通过以下方式实现跨域共享:

    • 主站将 Token 存储于 LocalStorage,并通过 postMessage 传递给管理后台的 iframe 页面,写入其 LocalStorage。
    • 管理后台前端每次请求时携带 Token,后端验证通过后建立局部会话,用户无需重复登录。

二、如何实现单点登录?

场景一:同域名下的单点登录(子域共享 Cookie)

适用场景:同一主域名下的子系统(如 shop.xxx.comadmin.xxx.com)。
实现原理:利用 Cookie 的 domainpath 属性跨子域共享会话标识。

步骤(以 Vue3 为例):

  1. 设置认证中心 Cookie
    在认证中心登录成功后,将 Session ID 写入 Cookie,配置:

    document.cookie = `sessionId=xxx; domain=.xxx.com; path=/; secure; HttpOnly`;
    
    • domain=.xxx.com:允许所有子域访问该 Cookie。
    • path=/:根路径下所有资源均可读取。
  2. 子系统验证会话
    子系统(如 Vue3 应用)在路由守卫中检查 Cookie 中的 sessionId

    // Vue3 路由守卫
    router.beforeEach((to, from, next) => {const sessionId = document.cookie.match(/sessionId=([^;]+)/)?.[1];if (to.meta.requiresAuth && !sessionId) {next(`/sso/login?redirect=${encodeURIComponent(to.fullPath)}`); // 跳转认证中心} else {next();}
    });
    

优势:实现简单,无需后端复杂逻辑;局限:仅适用于同主域名场景。

场景二:不同域名下的单点登录(标准 SSO 方案)

适用场景:跨域名系统(如 react-app.comvue-app.com)。
核心方案:基于 认证中心 + 令牌校验 的分布式架构。

方案一:后端主导的重定向认证(通用方案)

技术栈:认证中心(Node.js/Java) + 子系统(React/Vue3)。
流程步骤

  1. 用户访问子系统(React 应用)
    子系统检测到未登录,重定向至认证中心,并携带回调地址:

    // React 前端重定向
    window.location.href = `https://sso.com/login?redirect=https://react-app.com/dashboard`;
    
  2. 认证中心处理登录

    • 用户输入凭证,认证中心验证通过后生成 JWT 令牌,并存储用户会话(如 Redis)。

    • 重定向回子系统,附带令牌参数:

      // 认证中心 Node.js 后端
      app.get('/login', (req, res) => {// 验证用户逻辑...const token = generateJWT(user.id);res.redirect(`${req.query.redirect}?token=${token}`);
      });
      
  3. 子系统校验令牌
    子系统(Vue3 应用)后端接收令牌,调用认证中心接口验证合法性:

    // Vue3 后端(Node.js)
    app.get('/dashboard', async (req, res) => {const token = req.query.token;const isValid = await fetch(`https://sso.com/verify-token?token=${token}`); // 校验令牌if (isValid) {// 创建局部会话(如设置子系统 Cookie)res.cookie('localSession', 'valid', { domain: 'vue-app.com' });res.send('受保护资源');} else {res.redirect('/login');}
    });
    

优势:安全性高,支持跨域;劣势:需要后端深度参与,流程较复杂。

方案二:前端主导的 LocalStorage 共享(轻量级方案)

技术栈:纯前端(React + Vue3) + 认证中心 API。
核心逻辑:通过 iframe + postMessage 跨域传递 Token 至各系统的 LocalStorage。

实现步骤(以 React 为例):

  1. 认证中心返回 Token 给主系统

    // React 主系统登录回调
    const handleLogin = async () => {const response = await fetch('https://sso.com/login', { method: 'POST', body: formData });const { token } = await response.json();// 存储主系统 TokenlocalStorage.setItem('mainToken', token);// 通过 iframe 向 Vue3 子系统传递 Tokenconst iframe = document.createElement('iframe');iframe.src = 'https://vue-app.com/sso-helper'; // Vue3 子系统的跨域接收页面document.body.appendChild(iframe);setTimeout(() => {iframe.contentWindow.postMessage(token, 'https://vue-app.com'); // 安全限制目标域名}, 1000);
    };
    
  2. Vue3 子系统接收 Token
    创建 sso-helper.html 页面(Vue3 项目静态文件),监听跨域消息并存储 Token:

    <!-- Vue3 子系统 sso-helper.html -->
    <script>window.addEventListener('message', (event) => {if (event.origin === 'https://react-app.com') { // 验证来源域名localStorage.setItem('vueToken', event.data);}});
    </script>
    
  3. 各系统请求携带 Token
    前端每次发请求时从 LocalStorage 读取 Token 并添加到请求头:

    // React 全局 Axios 拦截器
    axios.interceptors.request.use(config => {config.headers.Authorization = `Bearer ${localStorage.getItem('mainToken')}`;return config;
    });
    

优势:后端无侵入,部署灵活;风险:依赖前端安全性,需严格校验消息来源域名。

三、单点登录核心流程与代码示例

流程时序图

在这里插入图片描述

关键代码片段(跨域场景)
  1. 认证中心生成 Token(Node.js)

    const jwt = require('jsonwebtoken');
    app.post('/login', (req, res) => {const { username, password } = req.body;// 验证用户逻辑...const token = jwt.sign({ userId: '123' }, 'sso-secret-key', { expiresIn: '1h' });res.json({ token }); // 返回给前端,由前端处理跨域传递
    });
    
  2. React 前端跨域传递 Token 至 Vue3

    // React 登录成功后
    const sendTokenToVueApp = (token) => {const iframe = document.createElement('iframe');iframe.style.display = 'none';iframe.src = 'https://vue-app.com/sso-iframe'; // Vue3 接收页面document.body.appendChild(iframe);iframe.onload = () => {iframe.contentWindow.postMessage({ type: 'SSO_TOKEN', token },'https://vue-app.com');};
    };
    
  3. Vue3 前端监听跨域消息

    // Vue3 主文件 main.js
    mounted() {window.addEventListener('message', this.handleSSOMessage);
    },
    methods: {handleSSOMessage(event) {if (event.origin === 'https://react-app.com' && event.data.type === 'SSO_TOKEN') {localStorage.setItem('ssoToken', event.data.token);this.$router.push('/dashboard'); // 自动跳转已登录页面}}
    }
    

    四、常见问题与解决方案

    1. 跨域 Cookie 共享限制
      • 同域名场景通过 domain 属性解决,不同域名需依赖认证中心重定向或前端跨域通信(如 postMessage)。
    2. 令牌安全性
      • 使用 HTTPS 传输 Token,避免明文泄露;
      • 令牌设置短有效期(如 1 小时),搭配刷新令牌(Refresh Token)机制续期。
    3. 单点登出(SLO)
      • 全局登出时,认证中心需销毁全局会话,并通知所有子系统销毁局部会话(可通过广播消息或子系统主动校验令牌失效)。

五、技术选型总结

场景推荐方案技术栈示例优势
同域名子系统Cookie 共享React + Express简单高效,后端轻量级
跨域名企业系统认证中心 + 重定向校验Vue3 + Spring Boot + Redis安全性高,符合企业级规范
纯前端跨域应用LocalStorage + postMessageReact + Vue3 + Node.js前端主导,后端无侵入

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/82445.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaWebsocket-demo

Websocket客户端 pom依赖 <dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.4.0</version></dependency>客户端代码片段 Component Slf4j public class PositionAlarmL…

Java Collection(集合) 接口

Date: 2025-05-21 20:21:32 author: lijianzhan Java 集合框架提供了一组接口和类&#xff0c;以实现各种数据结构和算法。 以下是关于 Java 集合的核心内容说明&#xff1a; /*** Java Collection Framework 说明&#xff1a;** 在 Java 中&#xff0c;集合&#xff08;Collec…

让MySQL更快:EXPLAIN语句详尽解析

前言 在数据库性能调优中&#xff0c;SQL 查询的执行效率是影响系统整体性能的关键因素之一。MySQL 提供了强大的工具——EXPLAIN 语句&#xff0c;帮助开发者和数据库管理员深入分析查询的执行计划&#xff0c;从而发现潜在的性能瓶颈并进行针对性优化。 EXPLAIN 语句能够模…

Java基础 Day20

一、HashSet 集合类 1、简介 HashSet 集合底层采取哈希表存储数据 底层是HashMap 不能使存取有序 JDK8之前的哈希表是数组和链表&#xff0c;头插法 JDK8之后的哈希表是数组、链表和红黑树&#xff0c;尾插法 2、存储元素 &#xff08;1&#xff09;如果要保证元素的唯…

2505C++,32位转64位

原文 假设有个想要将一个32位值传递给一个带64位值的函数的函数.你不关心高32位的内容,因为该值是传递给回调函数的直通值,回调函数会把它截断为32位值. 因此,你都担心编译器一般生成的将32位值扩展到64位值的那条指令的性能影响. 我怀疑这条指令不是程序中的性能瓶颈. 我想出…

光伏电站及时巡检:守护清洁能源的“生命线”

在“双碳”目标驱动下&#xff0c;光伏电站作为清洁能源的主力军&#xff0c;正以年均20%以上的装机增速重塑全球能源格局。然而&#xff0c;这些遍布荒漠、屋顶的“光伏矩阵”并非一劳永逸的能源提款机&#xff0c;其稳定运行高度依赖精细化的巡检维护。山东枣庄触电事故、衢州…

C++初阶-list的使用2

目录 1.std::list::splice的使用 2.std::list::remove和std::list::remove_if的使用 2.1remove_if函数的简单介绍 基本用法 函数原型 使用函数对象作为谓词 使用普通函数作为谓词 注意事项 复杂对象示例 2.2remove与remove_if的简单使用 3.std::list::unique的使用 …

OpenHarmony平台驱动使用(一),ADC

OpenHarmony平台驱动使用&#xff08;一&#xff09; ADC 概述 功能简介 ADC&#xff08;Analog to Digital Converter&#xff09;&#xff0c;即模拟-数字转换器&#xff0c;可将模拟信号转换成对应的数字信号&#xff0c;便于存储与计算等操作。除电源线和地线之外&#…

CSS【详解】弹性布局 flex

适用场景 一维&#xff08;行或列&#xff09;布局 基本概念 包裹所有被布局元素的父元素为容器 所有被布局的元素为项目 项目的排列方向&#xff08;垂直/水平&#xff09;为主轴 与主轴垂直的方向交交叉轴 容器上启用 flex 布局 将容器的 display 样式设置为 flex 或 i…

基于MATLAB实现传统谱减法以及两种改进的谱减法(增益函数谱减法、多带谱减法)的语音增强

基于MATLAB实现传统谱减法以及两种改进的谱减法&#xff08;增益函数谱减法、多带谱减法&#xff09;的语音增强代码示例&#xff1a; 传统谱减法 function enhanced traditional_spectral_subtraction(noisy, fs, wlen, inc, NIS, a, b)% 参数说明&#xff1a;% noisy - 带…

symbol【ES6】

你一闭眼世界就黑了&#xff0c;你不是主角是什么&#xff1f; 目录 什么是Symbol&#xff1f;‌Symbol特点‌&#xff1a;创建方法&#xff1a;注意点&#xff1a;不能进行运算&#xff1a;显示调用toString() --没有意义隐式转换boolean 如果属性名冲突了怎么办&#xff1f;o…

LeetCode 649. Dota2 参议院 java题解

https://leetcode.cn/problems/dota2-senate/description/ 贪心。不会写。 class Solution {public String predictPartyVictory(String senate) {boolean rtrue,dtrue;int flag0;//flag>0,d前面有r;flag<0,r前面有dchar[] senatessenate.toCharArray();//每一轮while(r…

机器学习第二十二讲:感知机 → 模仿大脑神经元的开关系统

机器学习第二十二讲&#xff1a;感知机 → 模仿大脑神经元的开关系统 资料取自《零基础学机器学习》。 查看总目录&#xff1a;学习大纲 关于DeepSeek本地部署指南可以看下我之前写的文章&#xff1a;DeepSeek R1本地与线上满血版部署&#xff1a;超详细手把手指南 感知机详解…

maven快速上手

之前我们项目如果要用到其他额外的jar包&#xff0c;需要自己去官网下载并且导入。但是有maven后&#xff0c;直接在maven的pom.xml文件里用代码配置即可&#xff0c;配置好后maven会自动帮我们联网下载并且会自动导入该jar包 在右边的maven中&#xff0c;我们可以看到下载安装…

科学养生指南:解锁健康生活密码

健康是人生最宝贵的财富&#xff0c;在快节奏的现代生活中&#xff0c;科学养生成为保持良好状态的关键。遵循现代医学与营养学的研究成果&#xff0c;无需依赖传统中医理论&#xff0c;我们也能找到适合自己的养生之道。​ 均衡饮食是健康的基石。现代营养学强调 “食物多样&…

Qt状态机QStateMachine

QStateMachine QState 提供了一种强大且灵活的方式来表示状态机中的状态&#xff0c;通过与状态机类(QStateMachine)和转换类(QSignalTransition&#xff0c; QEventTransition)结合&#xff0c;可以实现复杂的状态逻辑和用户交互。合理使用嵌套状态机、信号转换、动作与动画、…

C++八股 —— 原子操作

文章目录 1. 什么是原子操作2. 原子操作的特点3. 原子操作的底层原理4. 内存序内存屏障 5. 原子操作和互斥锁的对比6. 常用的原子操作7. 相关问题讨论 参考&#xff1a; C atomic 原子操作_c 原子操作-CSDN博客DeepSeek 1. 什么是原子操作 原子操作&#xff08;Atomic Opera…

双紫擒龙紫紫红指标源码学习,2025升级版紫紫红指标公式-重点技术

VAR1:MA((LOWHIGHCLOSE)/3,5); VAR2:CLOSEHHV(C,4) AND REF(C,1)LLV(C,4); 双紫擒龙:REF(C,1)LLV(C,4) AND C>REF(C,2) OR REF(C,2)LLV(C,4) AND REF(C,1)<REF(C,3) AND REF(C,2)<REF(C,4) AND C>REF(C,1); VAR4:VAR1>REF(VAR1,1) AND REF(VAR1,1)<REF(VAR1,…

NeuralRecon技术详解:从单目视频中实现三维重建

引言 三维重建是计算机视觉领域中的一项关键技术&#xff0c;它能够从二维图像中恢复出三维形状和结构。随着深度学习的发展&#xff0c;基于学习的方法已经成为三维重建的主流。NeuralRecon是一种先进的三维重建方法&#xff0c;它能够从单目视频中实时生成高质量的三维模型。…

Ubuntu 上开启 SSH 服务、禁用密码登录并仅允许密钥认证

1. 安装 OpenSSH 服务 如果尚未安装 SSH 服务&#xff0c;运行以下命令&#xff1a; sudo apt update sudo apt install openssh-server2. 启动 SSH 服务并设置开机自启 sudo systemctl start ssh sudo systemctl enable ssh3. 生成 SSH 密钥对&#xff08;本地机器&#xf…