Vue.js 单点登录(SSO)实现完全指南
一、什么是单点登录(SSO)
单点登录(Single Sign-On,简称SSO)是一种身份验证机制,用户只需在一个系统中登录一次,即可访问所有相互信任的关联系统,而无需重复认证。例如,登录Google账号后可以直接使用Gmail、YouTube、Google Drive等服务。
SSO的核心流程可以概括为:
- 用户访问子系统A,被重定向至中央认证中心
- 用户在认证中心登录后,认证中心颁发令牌(Token)
- 子系统A通过验证令牌获取用户信息
- 用户访问子系统B时,重复验证令牌流程,无需再次登录
对于前端Vue.js应用而言,实现SSO的核心职责包括:检测登录状态、处理认证跳转、管理Token令牌、以及跨应用同步登录状态。
二、SSO的主流实现方式对比
根据2024-2026年的前端实践,SSO主要有三种落地方式:
方式一:基于Cookie的域共享(传统方式)
适用场景:所有应用在同一顶级域下(如 app1.company.com、app2.company.com、sso.company.com)。
核心机制:SSO服务器设置Cookie时指定domain=.company.com; Secure; HttpOnly; SameSite=Lax,浏览器在所有子域自动携带该Cookie。
优缺点:浏览器原生支持,前端几乎无感实现;但仅限子域场景,无法跨顶级域。企业内网、传统ToB系统仍大量使用,但新项目已逐步转向Token模式。
方式二:基于Token的集中式认证(当前最推荐)
适用场景:跨顶级域、多前端框架(React/Vue/Next.js)、移动端与Web混合。
核心流程(OIDC + Authorization Code + PKCE + Refresh Token):
- 用户访问任意前端应用 → 未登录 → 重定向到SSO中心
- SSO中心登录成功 → 返回授权码(code)
- 前端用PKCE换取Token(access_token + refresh_token)
- 前端存储Token并携带在后续请求的Header中
优点:跨域支持好,不依赖第三方Cookie,安全性高,是当前主流方案。
方式三:iframe + postMessage通信(过渡方案)
适用场景:遗留系统集成、临时桥接。
核心机制:业务应用通过window.open弹出登录中心,登录成功后利用postMessageAPI 将Token安全传递回主应用。
局限性:受浏览器隐私策略限制(第三方Cookie逐步淘汰),已不再是推荐方案。
三、Vue.js前端SSO实现的完整步骤
1. 系统架构设计
一个典型的SSO系统包含三个核心角色:
- 认证中心(Auth Server):独立的前端应用或服务,负责统一身份认证、Token发放与登录状态管理
- 业务应用(Client):Vue.js构建的前端应用,提供具体业务功能,依赖登录状态访问受保护资源
- 后端服务(Backend):提供API接口,通过校验Token合法性控制资源访问
在技术选型上,常见组合为:Vue(前端) + JWT(令牌) + OAuth2.0/OIDC(协议)。
2. 配置路由守卫
路由守卫是SSO实现的第一道防线,用于拦截未登录用户的访问请求。
Vue Router全局前置守卫示例:
// router.jsimportrouterfrom'./router';importstorefrom'./store';router.beforeEach((to,from,next)=>{constisAuthenticated=store.getters['auth/isLoggedIn'];// 如果路由需要认证且用户未登录,跳转到登录页if(to.meta.requiresAuth&&!isAuthenticated){next({path:'/login',query:{redirect:to.fullPath}});}else{next();}});更完整的SSO路由守卫逻辑:
router.beforeEach(async(to,from,next)=>{letuserInfo=storageLocal().getItem(userKey);// 检查本地缓存if(!userInfo){letcurrentUrl=window.location.href;// 1. 检测是否为SSO回调(URL中带有授权码)constmatch=currentUrl.match(/code=([^&#]*)/);constcode=match?match[1]:null;if(code){// 2. 有授权码 → 用code换取token和用户信息awaitloginByCode(code);}elseif(to.query.type==='sso'){// 3. 需要SSO认证 → 跳转到认证中心currentUrl=currentUrl.replace('sso','sse');// 防止死循环constssoUrl=awaitgetSsoUri(currentUrl);window.location.href=ssoUrl;}}// 再次检查用户信息,决定跳转目标userInfo=storageLocal().getItem(userKey);if(!userInfo){// 跳转到登录页}next();});关键要点:
- 使用
to.meta.requiresAuth标记需要认证的路由 - 检测URL中的授权码(code)参数,完成认证回调处理
- 通过
query参数(如type=sso)触发SSO跳转流程 - 注意防止死循环跳转(如将
sso替换为sse)
3. 登录跳转与Token处理
当检测到用户未登录时,前端需要将用户重定向到认证中心。
登录跳转实现:
// Login.vueexportdefault{methods:{redirectToAuthServer(){constauthUrl=`${authServerUrl}/login?client_id=${clientId}&redirect_uri=${encodeURIComponent(window.location.origin+'/callback')}`;window.location.href=authUrl;},// 回调页面解析TokenhandleCallback(){consttoken=this.$route.query.token;if(token){this.$store.dispatch('auth/saveToken',token);this.$router.replace(this.$route.query.redirect||'/');}}}}处理认证回调的关键步骤:
- 前端通过重定向将用户引导至认证中心,携带
redirect_uri参数 - 认证中心登录成功后,携带授权码(code)或Token重定向回前端
- 前端在回调页面解析URL参数,获取Token并存储
优化技巧:将登录流程完全置于Vue Router的控制之下,利用导航守卫和编程式导航来管理状态,避免硬刷新带来的体验问题。当检测到code时,可以在守卫中挂起导航(返回pending Promise),待Token获取完成后再通过router.replace()完成无痕路由替换。
4. Token存储与管理
Token的存储和管理是SSO实现的核心环节。
使用Vuex/Pinia进行状态管理:
// store/auth.jsconststate={token:null};constmutations={SET_TOKEN(state,token){state.token=token;localStorage.setItem('jwt',token);// 持久化存储},CLEAR_TOKEN(state){state.token=null;localStorage.removeItem('jwt');}};constactions={saveToken({commit},token){commit('SET_TOKEN',token);},logout({commit}){commit('CLEAR_TOKEN');// 跳转到登录页window.location.href='/login';}};Token存储的安全建议:
- Access Token:建议存储在内存中(Pinia/Vuex状态),配合XSS防护
- Refresh Token:建议存储在HttpOnly Cookie中,防止XSS攻击窃取
- 本地存储(localStorage):方便页面刷新后恢复状态,但需注意XSS风险
在Vue 3项目中,推荐使用Pinia进行Token状态管理,它更简洁、类型支持更好。
5. 全局Axios拦截器
Axios拦截器负责在每次请求中自动携带Token,并处理Token过期时的自动刷新。
请求拦截器:自动在请求头中添加Token
// axios.jsimportaxiosfrom'axios';importstorefrom'./store';axios.interceptors.request.use(config=>{consttoken=store.getters['auth/token'];if(token){config.headers.Authorization=`Bearer${token}`;}returnconfig;});响应拦截器:处理401未授权错误,触发重新登录
axios.interceptors.response.use(response=>response,error=>{if(error.response.status===401){store.dispatch('auth/logout');window.location.href='/login';}returnPromise.reject(error);});Token无感刷新机制:
- 在请求拦截器中检查Token是否即将过期,若是则先发起静默刷新请求
- 在响应拦截器中检测401状态,自动刷新Token并重试原请求
- 多个请求同时失败时,使用请求队列避免重复刷新
四、弹窗 + postMessage 模式(可选方案)
除了整页重定向,弹窗模式是另一种常见的SSO交互方式,用户体验更佳。
核心流程
1. 触发登录:业务应用检测到未登录状态后,通过window.open打开登录中心弹窗
// 响应拦截器中触发登录弹窗request.interceptors.response.use((res)=>{if(res.data.status===401){window.open(`http://sso-server.com/login?resource=${window.location.origin}`);}returnres;});2. 监听回调:业务应用注册message事件监听,接收登录中心传递的Token
// main.js 中注册监听window.addEventListener('message',(event)=>{// 严格校验发送方的origin,防止恶意伪造if(event.origin!=='http://sso-server.com')return;const{token}=event.data;if(token){store.dispatch('auth/saveToken',token);}});3. 安全校验:必须严格校验event.origin,防止恶意网站伪造消息
五、常见SSO协议的前端对接
OAuth2.0 / OIDC 协议
OAuth2.0 + OpenID Connect(OIDC)是目前最主流的SSO协议方案。前端主要工作包括:
- 选择合适的SSO协议和服务
- 在Vue项目中配置SSO相关的库和插件
- 实现授权码流程(Authorization Code Flow)
- 处理认证后的用户信息
社区方案:可使用@ztzx/vue-sso-interceptor等Vue 3 SSO插件,它提供了完整的OAuth2/OIDC认证流程支持,包括自动路由守卫、Token管理、Pinia状态集成等功能。
CAS协议
CAS(Central Authentication Service)是另一种开源的单点登录协议。在Vue项目中集成CAS的要点:
- 配置CAS服务器地址
- 在路由守卫中判断无Token时跳转到CAS认证中心(替换原有的登录页跳转逻辑)
- 处理CAS回调,获取Ticket并换取用户信息
核心改造思路:将CAS认证流程从“后端驱动、浏览器自动跳转”转变为“前端感知、主动协作”的API调用模式。
六、安全最佳实践
1. Token安全存储
- Access Token避免存储在localStorage(易受XSS攻击)
- Refresh Token使用HttpOnly Cookie存储
- 考虑使用内存存储 + 定期刷新的组合方案
2. 防止CSRF攻击
- 使用SameSite Cookie属性
- 在请求中添加CSRF Token
- 使用PKCE(Proof Key for Code Exchange)增强授权码流程安全性
3. 跨域安全
- 严格校验postMessage的
event.origin - 合理配置CORS策略
- 避免在前端暴露敏感信息(如client_secret)
4. 登出处理
- 清除前端本地存储的Token
- 调用后端登出接口
- 跳转到SSO中心的全局登出页面,实现“一处登出,处处登出”
七、2026年趋势与挑战
随着浏览器隐私策略的收紧(第三方Cookie逐步被禁用),SSO前端实现正经历重要变革:
- 第三方Cookie基本被禁用:Chrome已100%推进,传统依赖Cookie的SSO方案受到冲击
- Storage Partitioning:不同顶级域的localStorage相互隔离
- 演进方向:从“纯Cookie共享” → “纯Token集中式” → “混合/BFF模式”成为主流路径
对于Vue前端开发者而言,基于Token的集中式认证(OIDC + PKCE + Refresh Token)是当前最推荐的SSO实现方案,具有良好的跨域支持和浏览器兼容性。
八、总结
在Vue.js中实现单点登录,前端主要承担以下职责:
- 配置身份验证服务:选择合适的SSO协议(OAuth2/OIDC/CAS)和认证服务
- 配置路由守卫:保护需要认证的路由,拦截未登录访问
- 处理认证回调:解析授权码,换取并存储Token
- 实现全局状态管理:使用Vuex或Pinia集中管理用户登录状态
- 配置请求拦截器:自动携带Token,处理Token过期刷新
通过以上步骤,Vue前端应用可以完整实现“一次登录,多系统通行”的SSO能力,在提升用户体验的同时保障系统安全。
