当前位置: 首页 > news >正文

Vue 3 版本的 JWT 单点登录 (SSO) 实现

单点认证体系(SSO)作为现代身份管理的重要组成部分,通过统一的认证机制实现了跨系统访问的无缝衔接。以下从用户终端视角剖析该系统的运行机制。

  1. 系统架构组成
    单点认证体系主要包含三大核心模块:

认证服务中心:作为整个体系的核心枢纽,承担用户身份核验、凭证签发和会话管理的职责。该服务通常采用集中式部署,为所有关联应用提供标准化的认证接口。

接入应用系统:指需要用户身份验证的各类业务系统。这些系统通过标准化协议与认证中心对接,在用户访问时自动完成认证流程。

用户终端环境:作为认证流程的起点和交互界面,通常指用户使用的浏览器或移动应用。终端负责维护认证状态,并在各应用间传递认证凭证。

这种架构设计通过将认证逻辑从业务系统中剥离,实现了"一次认证,全网通行"的效果。各业务系统无需单独维护用户凭证,只需信任认证中心颁发的令牌即可完成用户识别。

  1. 前端应用入口 (Vue 3 版本)
<template><div><div v-if="isLoading">加载中...</div><div v-else-if="!isAuthenticated">正在重定向到登录页面...</div><div v-else><header><p>欢迎, {{ user.name }}</p><button @click="handleLogout">退出登录</button></header><main><!-- 应用内容 --></main></div></div>
</template><script>
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router';export default {name: 'TokenBasedApp',setup() {const isAuthenticated = ref(false);const user = ref(null);const isLoading = ref(true);const router = useRouter();const redirectToSSOLogin = () => {const appId = 'app1';const callbackUrl = encodeURIComponent(window.location.origin);window.location.href = `https://sso.example.com/login?appId=${appId}&callback=${callbackUrl}`;};const validateToken = async () => {const token = localStorage.getItem('auth_token');if (!token) {isLoading.value = false;redirectToSSOLogin();return;}try {const response = await fetch('https://app1.example.com/api/auth/validate', {headers: {'Authorization': `Bearer ${token}`}});if (response.ok) {const userData = await response.json();isAuthenticated.value = true;user.value = userData;isLoading.value = false;} else {localStorage.removeItem('auth_token');isLoading.value = false;redirectToSSOLogin();}} catch (error) {console.error('Token验证失败:', error);isLoading.value = false;redirectToSSOLogin();}};const handleLogout = () => {localStorage.removeItem('auth_token');const callbackUrl = encodeURIComponent(window.location.origin);window.location.href = `https://sso.example.com/logout?callback=${callbackUrl}`;};onMounted(() => {const urlParams = new URLSearchParams(window.location.search);const token = urlParams.get('token');if (token) {localStorage.setItem('auth_token', token);window.history.replaceState({}, document.title, window.location.pathname);}validateToken();});return {isAuthenticated,user,isLoading,handleLogout};}
};
</script>
  1. JWT 登录页面 (Vue 3 版本)
<template><div class="login-container"><h2>统一登录平台</h2><div v-if="error" class="error-message">{{ error }}</div><form @submit.prevent="handleSubmit"><div class="form-group"><label for="username">用户名</label><inputtype="text"id="username"v-model="username"required/></div><div class="form-group"><label for="password">密码</label><inputtype="password"id="password"v-model="password"required/></div><button type="submit" :disabled="isLoading">{{ isLoading ? '登录中...' : '登录' }}</button></form></div>
</template><script>
import { ref } from 'vue';
import { useRoute } from 'vue-router';export default {name: 'JWTLoginPage',setup() {const username = ref('');const password = ref('');const error = ref(null);const isLoading = ref(false);const route = useRoute();const handleSubmit = async () => {isLoading.value = true;error.value = null;try {const appId = route.query.appId;const callbackUrl = route.query.callback;if (!appId || !callbackUrl) {throw new Error('缺少必要的参数');}const response = await fetch('https://sso.example.com/api/token', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({ username: username.value, password: password.value,appId})});if (!response.ok) {const errorData = await response.json();throw new Error(errorData.message || '登录失败');}const { token } = await response.json();window.location.href = `${decodeURIComponent(callbackUrl)}?token=${token}`;} catch (err) {error.value = err.message;isLoading.value = false;}};return {username,password,error,isLoading,handleSubmit};}
};
</script><style scoped>
.login-container {max-width: 400px;margin: 0 auto;padding: 20px;
}.form-group {margin-bottom: 15px;
}label {display: block;margin-bottom: 5px;
}input {width: 100%;padding: 8px;box-sizing: border-box;
}button {padding: 10px 15px;background-color: #42b983;color: white;border: none;cursor: pointer;
}button:disabled {background-color: #cccccc;cursor: not-allowed;
}.error-message {color: red;margin-bottom: 15px;
}
</style>

单点登录sso的实现可以归纳为如下:

  1. 所有客户端的登录默认都走一个页面
  2. 前端应用入口:进入业务页面时,
    ① 先校验是否携带的token,如果没有则直接携带appid和当前url跳转登录页。
    ②如果携带token,调接口查询token是否正常,正常则获取用户信息
    ③token不正常,携带appid和当前url跳转登录页
  3. JWT 登录页面 :页面获取从业务页面携带的appid和callbackUrl,使用统一登录,成功后,通过callbackUrl和token,跳转回原业务页面,继续走获取用户信息的方法。
http://www.dtcms.com/a/314347.html

相关文章:

  • 国家科学技术奖答辩PPT案例_科技进步奖ppt制作_技术发明奖ppt设计美化_自然科学奖ppt模板 | WordinPPT
  • 使用mybatis生成器生成实体类mapper和查询参数文件,实现简单增删改查。使用log4j输出日志到控制台。使用配置文件注册Bean,配置视图解析器
  • 【Java】使用模板方法模式设计EasyExcel批量导入导出
  • Apache Camel 中 ProducerTemplate
  • 刷题日志(7)——二叉树高频习题(下)
  • 高精度实战:YOLOv11交叉口目标行为全透视——轨迹追踪×热力图×滞留分析(附完整代码)
  • FrePrompter: Frequency self-prompt for all-in-one image restoration
  • Opencv[一]
  • R 语言科研绘图第 67 期 --- 箱线图-显著性
  • Spark SQL:用SQL玩转大数据
  • OpenCV轻松入门_面向python(第二章图像处理基础)
  • 论文阅读笔记:《Dataset Distillation by Matching Training Trajectories》
  • 【数据结构初阶】--算法复杂度详解
  • 登录弹窗,cv直接使用
  • 【FreeRTOS】系统时钟配置
  • HTTP基本结构
  • ICCV 2025|单视频生成动态4D场景!中科大微软突破4D生成瓶颈,动画效果炸裂来袭!
  • ICCV 2025|可灵团队新作 ReCamMaster:从单视频到多视角生成,多角度看好莱坞大片
  • socket与udp
  • 折叠屏网页布局挑战:响应式设计在工业平板与PC端的弹性适配策略
  • 【Mac】OrbStack:桌面端虚拟机配置与使用
  • LeetCode 140:单词拆分 II
  • 【MySQL03】:MySQL约束
  • mac 技巧
  • 零售消费行业研究系列报告
  • Java-基础-统计投票信息
  • Linux下载安装mysql,客户端(Navicat)连接Linux中的mysql
  • allegro建库--1
  • 【Redis】移动设备离线通知推送全流程实现:系统推送服务与Redis的协同应用
  • 模型学习系列之考试