ruoyi-vue-pro数据大屏——纯前端单点登录

ruoyi-vue-pro数据大屏——纯前端单点登录

ruoyi-vue-pro 的已经集成了数据大屏模块go-view,并且用vue开发了前端,可以进行拖来拽就能实现一个精美的数据大屏应用,然而点击【报表管理->大屏设计】你却发现需要输入账号密码登陆,这多少有点遗憾。

ruoyi-vue-pro已经支持应用注册并进行oauth2的授权功能,然而最后一公里我们必须自己去走。

1、在【三方授权->应用管理】中注册数据大屏应用report

2、改造yudao-ui-go-view-master项目支持断点登陆

A)新增callback组件。

新增页面src/views/sso/callback.vue,内容如下:

<template> <!-- 登录 --> <div> </div> </template> <script lang="ts" setup> import { reactive, ref, onMounted } from 'vue' import { Router, useRoute } from 'vue-router'; import { ssoLoginCallbackApi } from '@/api/path' import { useSystemStore } from '@/store/modules/systemStore/systemStore' import { SystemStoreUserInfoEnum, SystemStoreEnum } from '@/store/modules/systemStore/systemStore.d' import { StorageEnum } from '@/enums/storageEnum'; import { PageEnum, PreviewEnum } from '@/enums/pageEnum' import { routerTurnByName } from '@/utils' import {getTenantIdByNameApi, getUserInfoApi, loginApi} from '@/api/path' const systemStore = useSystemStore() const t = window['$t'] onMounted(async () => { const route = useRoute(); const code = route.query.code; if(!code) { return; } var loginRes = await ssoLoginCallbackApi(code.toString()); if(loginRes && loginRes.data) { // ① Token 信息(先存储下,保证可以加载个人信息) const tokenValue = loginRes.data.access_token const tokenName = 'Authorization' systemStore.setItem(SystemStoreEnum.TENANT_INFO, { tenantId: 1 }) systemStore.setItem(SystemStoreEnum.USER_INFO, { [SystemStoreUserInfoEnum.USER_TOKEN]: tokenValue, [SystemStoreUserInfoEnum.TOKEN_NAME]: tokenName }) // 个人信息 const profileRes = await getUserInfoApi(); const id = profileRes?.data?.id; const username = profileRes?.data?.username; const nickname = profileRes?.data?.nickname; if(id && username && nickname){ // 存储到 pinia systemStore.setItem(SystemStoreEnum.USER_INFO, { [SystemStoreUserInfoEnum.USER_TOKEN]: tokenValue, [SystemStoreUserInfoEnum.TOKEN_NAME]: tokenName, [SystemStoreUserInfoEnum.USER_ID]: id, [SystemStoreUserInfoEnum.USER_NAME]: username, [SystemStoreUserInfoEnum.NICK_NAME]: nickname, }) window['$message'].success(t('login.login_success')) var sso_url = localStorage.getItem(StorageEnum.GO_SSO_URL); console.log("sso_url:"+sso_url) if(sso_url) { localStorage.removeItem(StorageEnum.GO_SSO_URL); window.location.href = sso_url; return; } routerTurnByName(sso_url || PageEnum.BASE_HOME_NAME, true) return; } window['$message'].error('登陆失败:'+profileRes.msg) routerTurnByName(PageEnum.ERROR_PAGE_NAME_403, true) } else { window['$message'].success(loginRes.msg); window['$message'].error('登陆失败:'+loginRes.msg) routerTurnByName(PageEnum.BASE_LOGIN_NAME, true) } }) </script> 

B)新增callback路由

在src\router\base.ts中找到LoginRoute,在后面新增代码:

export const SsoCallbackRoute: RouteRecordRaw = { path: PageEnum.SSO_CALL_BACK, name: PageEnum.SSO_CALL_BACK_NAME, component: () => import('@/views/sso/callback.vue'), meta: { title: '单点登录', }, };

在src\router\index.ts文件中导入

C)新增单点登陆api。

我这里数据大屏的是内网,而且后端使用的是ruoyi-vue-pro,所有appKey, appSecret都是写死在js中的,后期根据需要进行改造配置到后端application.yaml中。

在src\api\path\system.api.ts中,找到logoutApi,在其后新增单点登陆api如下:

 // * SSO登录 // 可以改写成,你的 clientId const clientId = 'yudao-sso-demo-by-code'; export const ssoLogin = () => { const redirectUri = encodeURIComponent('http://localhost:3000/callback'); // 注意,需要使用 encodeURIComponent 编码地址 const responseType = 'code'; // 1)授权码模式,对应 code;2)简化模式,对应 token window.location.href = 'https://192.168.1.222:80/sso?client_id=' + clientId + '&redirect_uri=' + redirectUri + '&response_type=' + responseType; } // * SSO登录 export const ssoLoginCallbackApi = async (code: String) => { try { const redirectUri = "http://localhost:3000/callback"; const url = "https://192.168.1.222:80/admin-api/system/oauth2/token?grant_type=authorization_code&code="+ code+"&redirect_uri="+redirectUri; const params = { } const headers = { "Content-Type": ContentTypeEnum.JSON, "tenant-id": "1", "Authorization": "Basic " + encode(new TextEncoder().encode(clientId+":datav123")) }; const config = { baseURL:'', headers: headers }; var res = await axios.post(url, params, config) console.log(res) return res.data } catch (err) { httpErrorHandle() } } // 单点登陆callback中调用,查询用户个人信息 export const getUserInfoApi = async () => { try { const res = await http(RequestHttpEnum.GET)<ProfileVO>(`${ModuleTypeEnum.SYSTEM}/oauth2/user/get`) return res } catch (err) { httpErrorHandle() } } 

D) 在路由守卫中拦截sso

在src\router\router-guards.ts文件中判断白名单前,新增代码如下:

 if(to && to.query && to.query.sso == 'true'){ localStorage.setItem(StorageEnum.GO_SSO_URL, window.location.href) // @ts-ignore if (!routerAllowList.includes(to.name) && !loginCheck()) { ssoLogin(); return; } }

E)处理后端返回未认证(状态码为401)

在src\api\axios.ts中新增代码,如果sso访问但未登陆成功或者token超时则发起单点登陆,代码如下:

3、改造yudao-vue-pro中的【报表管理->大屏设计】中的页面

只需要在url上加一个参数sso=true就行了只需要在url上加一个参数sso=true就行了只需要在url上加一个参数sso=true就行了

4、验证访问数据大屏

A)验证单点登录

重新启动yudao-vue-pro,yudao-ui-go-view,或刷新【报表管理->大屏设计】,将会出现授权请求页面如下:

这个页面是yudao-vue-pro中的src\views\sso.vue,这里我只是改了下样式,这个页面应该不需要改动。同意授权后页面会自动跳转到数据大屏的首页,如下图:

授权一次以后就可以愉快的访问了授权一次以后就可以愉快的访问了授权一次以后就可以愉快的访问了

B)验证在yudao-vue-pro中配置菜单直接访问数据看板

=============    相关博文   ============

ruoyi-vue-pro数据大屏——路由支持history,告别难看的hash路由

ruoyi-vue-pro数据大屏——单点登录,告别手输密码(适用于不带后端服务的情况)

ruoyi-vue-pro优化——如何将一个模块快速变成一个独立的应用进行开发,部署,管理

ruoyi-vue-pro增强——新增通用单点登录模块yudao-module-sso(下载链接在博文末尾)

ruoyi-vue-pro数据大屏优化——在yudao-module-report-app使用yudao-moudle-sso优化单点登录

ruoyi-vue-pro优化——让菜单支持多个参数,一键直达【经营分析】、【生产报表】、【销售报表】

ruoyi-vue-pro优化——模块单独打包,增量更新、部署,告别打包等待,上传等待,节省网络流量

=============    相关博文  ============

Read more

前端防范 XSS(跨站脚本攻击)

目录 一、防范措施 1.layui util  核心转义的特殊字符 示例 2.js-xss.js库 安装 1. Node.js 环境(npm/yarn) 2. 浏览器环境 核心 API 基础使用 1. 基础过滤(默认规则) 2. 自定义过滤规则 (1)允许特定标签 (2)允许特定属性 (3)自定义标签处理 (4)自定义属性处理 (5)转义特定字符 常见场景示例 1. 过滤用户输入的评论内容 2. 允许特定富文本标签(如富文本编辑器内容) 注意事项 更多配置 XSS(跨站脚本攻击)是一种常见的网络攻击手段,它允许攻击者将恶意脚本注入到其他用户的浏览器中。

详细教程:如何从前端查看调用接口、传参及返回结果(附带图片案例)

详细教程:如何从前端查看调用接口、传参及返回结果(附带图片案例)

目录 1. 打开浏览器开发者工具 2. 使用 Network 面板 3. 查看具体的API请求 a. Headers b. Payload c. Response d. Preview e. Timing 4. 实际操作步骤 5. 常见问题及解决方法 a. 无法看到API请求 b. 请求失败 c. 跨域问题(CORS) 作为一名后端工程师,理解前端如何调用接口、传递参数以及接收返回值是非常重要的。下面将详细介绍如何通过浏览器开发者工具(F12)查看和分析这些信息,并附带图片案例帮助你更好地理解。 1. 打开浏览器开发者工具 按下 F12 或右键点击页面选择“检查”可以打开浏览器的开发者工具。常用的浏览器如Chrome、Firefox等都内置了开发者工具。下面是我选择我的一篇文章,打开开发者工具进行演示。 2. 使用

Cursor+Codex隐藏技巧:用截图秒修前端Bug的保姆级教程(React/Chakra UI案例)

Cursor+Codex隐藏技巧:用截图秒修前端Bug的保姆级教程(React/Chakra UI案例) 前端开发中最令人头疼的莫过于那些难以定位的UI问题——元素错位、样式冲突、响应式失效...传统调试方式往往需要反复修改代码、刷新页面、检查元素。现在,通过Cursor编辑器集成的Codex功能,你可以直接用截图交互快速定位和修复这些问题。本文将带你从零开始,掌握这套革命性的调试工作流。 1. 环境准备与基础配置 在开始之前,确保你已经具备以下环境: * Cursor编辑器最新版(v2.5+) * Node.js 18.x及以上版本 * React 18项目(本文以Chakra UI 2.x为例) 首先在Cursor中安装Codex插件: 1. 点击左侧扩展图标 2. 搜索"Codex"并安装 3. 登录你的OpenAI账户(需要ChatGPT Plus订阅) 关键配置项: // 在项目根目录创建.