vben集成keycloak
前言
公司的项目是vben admin框架需要集成keycloak,那keycloak大家应该都不陌生了,就是统一认证的一个系统简称IDS。之前用过cas,并重构过cas的前端界面,所以对此也是比较熟悉。
在keycloak官网有个例子,不过他是相对于vue2时候的,现在大家都在用vue3 vite,所以生成vue事例不一样了,vue中我们都知道new Vue()中有个render ,可以在创建的element上添加props属性。可以在vue3中是creatApp(),这个就比较懵了,没有地方写props,那我的keycloak应该写在哪儿呢?
好了,废话不多说,直接上代码
1. 首先下载:yarn add @dsb-norge/vue-keycloak-js
2. 新增文件:src/keyCloak.ts
keyCloak.ts
import type { App } from 'vue';
import keycloak from '@dsb-norge/vue-keycloak-js';
export function setupKeyCloak(app: App<Element>, bootstrap) {
app.use(keycloak, {
init: {
onLoad: 'login-required',
checkLoginIframe: true, //防止登陆后重复刷新
},
config: {
url: 'http://60.215.255.22:8088/auth', // 你的keycloak地址
realm: 'OM',
clientId: 'om-cli',
},
onReady: (keycloak) => {
app.config.globalProperties.$keycloak = keycloak;
console.log(keycloak);
keycloak.loadUserProfile().success((data) => {
console.log(data);
bootstrap(keycloak.token);
});
},
});
}
3. 修改:src/main.ts
main.ts
import 'virtual:windi-base.css';
import 'virtual:windi-components.css';
import '/@/design/index.less';
import 'virtual:windi-utilities.css';
// Register icon sprite
import 'virtual:svg-icons-register';
import App from './App.vue';
import { createApp } from 'vue';
import { initAppConfigStore } from '/@/logics/initAppConfig';
import { setupErrorHandle } from '/@/logics/error-handle';
import { router, setupRouter } from '/@/router';
import { setupRouterGuard } from '/@/router/guard';
import { setupStore } from '/@/store';
import { setupGlobDirectives } from '/@/directives';
import { setupI18n } from '/@/locales/setupI18n';
import { registerGlobComp } from '/@/components/registerGlobComp';
import { setupKeyCloak } from '/@/keyCloak';
// 配置 keycloak
import { useUserStore } from '/@/store/modules/user';
const app = createApp(App);
setupKeyCloak(app, bootstrap);
async function bootstrap(token) {
// const app = createApp(App);
// Configure store
// 配置 store
setupStore(app);
// Initialize internal system configuration
// 初始化内部系统配置
initAppConfigStore();
// Register global components
// 注册全局组件
registerGlobComp(app);
// Multilingual configuration
// 多语言配置
// Asynchronous case: language files may be obtained from the server side
// 异步案例:语言文件可能从服务器端获取
await setupI18n(app);
// Configure routing
// 配置路由
setupRouter(app);
// router-guard
// 路由守卫
setupRouterGuard(router);
// Register global directive
// 注册全局指令
setupGlobDirectives(app);
// Configure global error handling
// 配置全局错误处理
setupErrorHandle(app);
// https://next.router.vuejs.org/api/#isready
// await router.isReady();
// 登陆方法修改
const userStore = useUserStore();
userStore.loginX(token);
app.mount('#app');
}
4. 添加loginX:src/store/modules/user.ts
5. 添加logoutX:src/store/modules/user.ts
6. 修改confirmLoginOut:src/store/modules/user.ts
点击查看代码
async loginX(token): Promise<GetUserInfoModel | null> {
try {
this.setToken(token);
return this.afterLoginAction(true);
} catch (error) {
return Promise.reject(error);
}
},
async logoutX(goLogin = false) {
this.setToken(undefined);
this.setUserInfo(null);
console.log('退出成功');
goLogin && router.replace(PageEnum.BASE_HOME);
// goLogin && router.push(PageEnum.BASE_LOGIN);
},
/**
* @description: Confirm before logging out
*/
confirmLoginOut(globalProperties) {
const { createConfirm } = useMessage();
const { t } = useI18n();
createConfirm({
iconType: 'warning',
title: () => h('span', t('sys.app.logoutTip')),
content: () => h('span', t('sys.app.logoutMessage')),
onOk: async () => {
await this.logoutX(true);
await globalProperties.$keycloak.logout();
},
});
},
7. 修改界面的退出登录:src/layouts/default/header/components/user-dropdown/index.vue
点击查看代码
<template>
<Dropdown placement="bottomLeft" :overlayClassName="`${prefixCls}-dropdown-overlay`">
<span :class="[prefixCls, `${prefixCls}--${theme}`]" class="flex">
<img :class="`${prefixCls}__header`" :src="getUserInfo.avatar" />
<span :class="`${prefixCls}__info hidden md:block`">
<span :class="`${prefixCls}__name `" class="truncate">
{{ getUserInfo.realName }}
</span>
</span>
</span>
<template #overlay>
<Menu @click="handleMenuClick">
<MenuItem
key="doc"
:text="t('layout.header.dropdownItemDoc')"
icon="ion:document-text-outline"
v-if="getShowDoc"
/>
<MenuDivider v-if="getShowDoc" />
<MenuItem
v-if="getUseLockPage"
key="lock"
:text="t('layout.header.tooltipLock')"
icon="ion:lock-closed-outline"
/>
<MenuItem
key="logout"
:text="t('layout.header.dropdownItemLoginOut')"
icon="ion:power-outline"
/>
</Menu>
</template>
</Dropdown>
<LockAction @register="register" />
</template>
<script lang="ts">
// components
import { Dropdown, Menu } from 'ant-design-vue';
import type { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import { defineComponent, computed, getCurrentInstance } from 'vue';
import { DOC_URL } from '/@/settings/siteSetting';
import { useUserStore } from '/@/store/modules/user';
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
import { useI18n } from '/@/hooks/web/useI18n';
import { useDesign } from '/@/hooks/web/useDesign';
import { useModal } from '/@/components/Modal';
import headerImg from '/@/assets/images/header.jpg';
import { propTypes } from '/@/utils/propTypes';
import { openWindow } from '/@/utils';
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
type MenuEvent = 'logout' | 'doc' | 'lock';
export default defineComponent({
name: 'UserDropdown',
components: {
Dropdown,
Menu,
MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
MenuDivider: Menu.Divider,
LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')),
},
props: {
theme: propTypes.oneOf(['dark', 'light']),
},
setup() {
const internalInstance = getCurrentInstance();
const { prefixCls } = useDesign('header-user-dropdown');
const { t } = useI18n();
const { getShowDoc, getUseLockPage } = useHeaderSetting();
const userStore = useUserStore();
const getUserInfo = computed(() => {
const { realName = '', avatar, desc } = userStore.getUserInfo || {};
return { realName, avatar: avatar || headerImg, desc };
});
const [register, { openModal }] = useModal();
function handleLock() {
openModal(true);
}
// d
function handleLoginOut() {
userStore.confirmLoginOut(internalInstance?.appContext.config.globalProperties);
}
// open doc
function openDoc() {
openWindow(DOC_URL);
}
function handleMenuClick(e: MenuInfo) {
switch (e.key as MenuEvent) {
case 'logout':
handleLoginOut();
break;
case 'doc':
openDoc();
break;
case 'lock':
handleLock();
break;
}
}
return {
prefixCls,
t,
getUserInfo,
handleMenuClick,
getShowDoc,
register,
getUseLockPage,
};
},
});
</script>
<style lang="less">
@prefix-cls: ~'@{namespace}-header-user-dropdown';
.@{prefix-cls} {
height: @header-height;
padding: 0 0 0 10px;
padding-right: 10px;
overflow: hidden;
font-size: 12px;
cursor: pointer;
align-items: center;
img {
width: 24px;
height: 24px;
margin-right: 12px;
}
&__header {
border-radius: 50%;
}
&__name {
font-size: 14px;
}
&--dark {
&:hover {
background-color: @header-dark-bg-hover-color;
}
}
&--light {
&:hover {
background-color: @header-light-bg-hover-color;
}
.@{prefix-cls}__name {
color: @text-color-base;
}
.@{prefix-cls}__desc {
color: @header-light-desc-color;
}
}
&-dropdown-overlay {
.ant-dropdown-menu-item {
min-width: 160px;
}
}
}
</style>
vben集成keycloak的更多相关文章
- VUE集成keycloak和Layui集成keycloak
一:KEYCLOAK配置部分: 1,下载keycloak,官网地址:https://www.keycloak.org/downloads.html.下载第一个就行 2,下载完毕之后,打开文件,访问 b ...
- jenkins 集成 keycloak 认证
keycloak 是很不错的sso 工具,当然也有Jenkins 的插件,我们可以使用jenkins 插件,方便用户账户的管理 环境准别 docker-compose version: "3 ...
- keycloak集成微信登陆~解决国内微信集成的问题
之前看了国内写的微信集成keycloak的文章,然后拿来就用了,但我的是jboss部署的keycloak,然后使用他的包之后,会出现类无法找到的问题,之后找了很多资料,多数都是国外的,在今天终于找到了 ...
- keycloak学习
keycloak 是一个针对Web应用和RESTfull Web API 提供SSO(Single Sign On:单点登陆),它是一个开源软件,源码地址是:https://github.com/ke ...
- ionic + asp.net core webapi + keycloak实现前后端用户认证和自动生成客户端代码
概述 本文使用ionic/angular开发网页前台,asp.net core webapi开发restful service,使用keycloak保护前台页面和后台服务,并且利用open api自动 ...
- Keycloak快速上手指南,只需10分钟即可接入Spring Boot/Vue前后端分离应用实现SSO单点登录
登录及身份认证是现代web应用最基本的功能之一,对于企业内部的系统,多个系统往往希望有一套SSO服务对企业用户的登录及身份认证进行统一的管理,提升用户同时使用多个系统的体验,Keycloak正是为此种 ...
- 开源认证和访问控制的利器keycloak使用简介
目录 简介 安装keycloak 创建admin用户 创建realm和普通用户 使用keycloak来保护你的应用程序 安装WildFly client adapter 注册WildFly应用程序 安 ...
- aspnetcore 应用 接入Keycloak快速上手指南
登录及身份认证是现代web应用最基本的功能之一,对于企业内部的系统,多个系统往往希望有一套SSO服务对企业用户的登录及身份认证进行统一的管理,提升用户同时使用多个系统的体验,Keycloak正是为此种 ...
- keycloak~自定义rest接口
rest资源 对于我们集成keycloak来说,你可能会遇到它没有实现的功能,这时需要对kc进行扩展,资源的扩展是其中一个方面,它需要实现RealmResourceProvider和RealmReso ...
- keycloak && docker安装 &&spring boot 集成使用
1. 基础依赖 a. docker mysql b. dokcer keycloak-mysql 2. 安装 mysql (注意实际使用最好使用本地数据卷) docker run --na ...
随机推荐
- 实例演示如何使用CCE XGPU虚拟化
本文分享自华为云社区<CCE XGPU虚拟化的使用>,作者: 可以交个朋友. 一 背景 在互联网场景中,用户的AI训练和推理任务对GPU虚拟化有着强烈的诉求.GPU卡作为重要的计算资源不管 ...
- #凸包,闵可夫斯基和#CF87E Mogohu-Rea Idol
题目 按逆时针顺序给出三个凸包点集 \(\mathbb{A,B,C}\),每次查询给出点 \(D\), 问是否存在点 \(A\in\mathbb{A},B\in\mathbb{B},C\in\math ...
- reactive stream协议详解
目录 背景 什么是reactive stream 深入了解java版本的reactive stream Publisher Subscriber Subscription Processor JDK中 ...
- C# 方法详解:定义、调用、参数、默认值、返回值、命名参数、方法重载全解析
C# Methods 方法是一段代码,只有在调用时才会运行. 您可以将数据(称为参数)传递给方法. 方法用于执行某些操作,也被称为函数. 为什么使用方法?为了重用代码:定义一次代码,然后多次使用. 创 ...
- [Java SE] 经典问题:超出Java Long型(8字节/64位)的二进制比特流数据如何进行大数的数值计算?
0 问题描述 经典问题:超出Java Long型(8字节/64位)的二进制比特流数据如何进行大数的数值计算? 近期工作上遇到了这个问题:需要将一个无符号数.且位长>=8字节(等于8字节时,首位b ...
- 重新点亮linux 命令树————网络管理[十一二]
前言 简单整理一下网络管理. 正文 网络管理需要掌握: 网络状态查看 网络配置 路由命令 网络故障排除 网络服务管理 常用网络配置文件 网络状态的查看: 1.net-tools ---->1.i ...
- c# 模拟web请求formdata webrequest
前言 在写代码中,我们常常需要去书写代码去请求一些东西,那么是不是可以模拟像web formdata一样请求. 正文 下面代码为模拟的: public string SendRequest(strin ...
- 为什么我要写spring.factories文件?
在阅读spring-boot相关源码时,常常见到spring.factories文件,里面写了自动配置(AutoConfiguration)相关的类名,因此产生了一个疑问:"明明自动配置的类 ...
- 深入解析Rivest Cipher 4:理论与实践
第一章:引言 密码学简介: 密码学是研究如何保护通信和信息安全的学科.它涉及加密算法.解密算法.密钥管理等内容,旨在确保信息在传输和存储过程中不被未经授权的人所获取或篡改.密码学可以分为对称加密和非对 ...
- 力扣138(java)- 复制带随机指针的链表(中等)
题目: 给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点. 构造这个链表的 深拷贝. 深拷贝应该正好由 n 个 全新 节点组成,其 ...