vue单点登录实现
Vue 单点登录实现方案
单点登录(SSO)允许用户通过一次登录访问多个关联系统。以下是基于 Vue 的实现方案:
使用 OAuth2.0/OpenID Connect 协议
-
配置认证服务器
选择 Keycloak、Auth0 或阿里云 IDaaS 等 SSO 服务提供商,注册应用并获取client_id和client_secret。
示例配置:// auth.config.js export default { issuer: 'https://your-sso-server.com', clientId: 'your-client-id', redirectUri: window.location.origin + '/callback' } -
集成 oidc-client-js 库
安装并初始化认证库:npm install oidc-client-js// auth.js import { UserManager } from 'oidc-client-js'; import config from './auth.config'; const userManager = new UserManager(config); export const login = () => userManager.signinRedirect(); export const logout = () => userManager.signoutRedirect(); -
处理回调页面
创建/callback路由组件处理登录响应:// Callback.vue mounted() { userManager.signinRedirectCallback() .then(user => { localStorage.setItem('sso_token', user.access_token); this.$router.push('/'); }); }
基于 JWT 的跨域方案
-
主系统登录后分发 Token
主系统登录成功后生成 JWT 并重定向到子系统:
// 主系统登录逻辑 const token = generateJWT(userInfo); window.location.href = `https://sub-system.com?token=${token}`; -
子系统验证 Token
子系统通过created钩子验证 Token:created() { const token = this.$route.query.token; if (token && validateJWT(token)) { axios.defaults.headers.common['Authorization'] = `Bearer ${token}`; } else { window.location.href = 'https://main-system.com/login'; } }
使用 CAS 协议
-
重定向到 CAS 服务器
未登录时跳转至 CAS 登录页:checkLogin() { if (!this.$store.state.isLoggedIn) { const service = encodeURIComponent(window.location.href); window.location.href = `https://cas-server.com/login?service=${service}`; } } -
验证 ST(Service Ticket)
在路由守卫中处理 CAS 回调:
router.beforeEach((to, from, next) => { if (to.query.ticket) { axios.post('/validate-ticket', { ticket: to.query.ticket }) .then(() => next('/')); } });
共享 Cookie 方案(同父域)
-
设置跨域 Cookie
主域.example.com设置 Cookie:document.cookie = `sso_token=${token}; domain=.example.com; path=/`; -
子域检测 Cookie
子域通过后端接口验证 Cookie:mounted() { axios.get('/api/verify-sso') .catch(() => window.location.href = 'https://sso.example.com'); }
注意事项
- 所有敏感操作需后端二次验证
- Token 应设置合理有效期
- 采用 HTTPS 保证传输安全
- 实现全局路由守卫检查认证状态
- 考虑使用 Vuex 集中管理认证状态
示例路由守卫实现:
router.beforeEach((to, from, next) => {
const isAuthenticated = store.getters.isAuthenticated;
if (to.meta.requiresAuth && !isAuthenticated) {
next('/login');
} else {
next();
}
});
以上方案可根据实际业务需求组合使用,建议优先选择标准协议如 OAuth2.0。






