使用 Vue 3 插件(Plugin)实现 OIDC 登录和修改密码(OIDC 系统以 Keycloak 为例)

这篇具有很好参考价值的文章主要介绍了使用 Vue 3 插件(Plugin)实现 OIDC 登录和修改密码(OIDC 系统以 Keycloak 为例)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

目前单位系统常用 Keycloak 作为认证系统后端,而前端之前写的也比较随意,这次用 Vue 3 插件以及 Ref 响应式来编写这个模块。另外,这个可能是全网唯一使用 keycloak 的 OIDC 原生更新密码流的介绍代码。

设计

依赖库选择

OIDC 客户端,这里选择 oidc-client-ts 来提供 OIDC 相关的服务,根据目前的调研这个算是功能比较齐全、兼容性比较好的 OIDC 客户端了。像 keycloak.js,其实也没有修改密码和自动刷新 token 的功能。另外像 Auth0 Vue SDK 则只能用于 Auth0,但他设计上还是不错的,也是通过 Vue 3 原生的插件功能实现的。

具体设计

根据 Vue 3 的官方插件文档,主要需要两部分组成,一个是需要定义一个 Plugin 并在里面使用 provide 来提供对象,另一个则是需要定义一个方法使用 inject 来接收提供的对象。

这里给原本的 oidc-client-ts 里的 UserManager 来个套娃,外层这个套一层,叫 AuthManager 。这样就可以将一些初始化时加载 LocalStorage 里的 token 等等逻辑封装在这里面,同时也可以对外暴露一些 Ref 让其他组件可以监听变化。

代码

废话不多说了,咱还是老样子,直接上代码

auth-manager.ts文章来源地址https://www.toymoban.com/news/detail-741804.html

import { UserManager, UserManagerSettings } from 'oidc-client-ts';
import { Plugin, inject, ref } from 'vue';

/**
 * 用于注入的 key
 */
const PROVIDE_KEY = Symbol('oidc-provider');
/**
 * 用户信息
 */
interface UserInfo {
  /**
   * 用户 id
   */
  userId: string;
  /**
   * 用户名
   */
  username: string;
  /**
   * token
   */
  token: string;
  /**
   * 姓
   */
  lastName: string;
  /**
   * 名
   */
  firstName: string;
  /**
   * 邮箱
   */
  email: string;
  /**
   * 认证时间
   */
  authTime: number;
  /**
   * 角色
   */
  roles: Array<string>;
}
/**
 * 认证管理器
 */
class AuthManager {
  /**
   * token
   */
  accessToken = ref('');
  /**
   * 用户信息
   */
  userInfo = ref<UserInfo>();
  /**
   * oidc 客户端
   */
  private oidc: UserManager;
  /**
   * 构造函数
   * @param settings oidc 客户端配置
   */
  constructor(settings: UserManagerSettings) {
    this.oidc = new UserManager(settings);
    // 当用户登录时,更新 token 和用户信息
    this.oidc.events.addUserLoaded((user) => {
      this.accessToken.value = user.access_token;
      this.userInfo.value = {
        userId: user.profile.sub,
        username: user.profile.preferred_username || '',
        token: user.access_token,
        lastName: '',
        firstName: '',
        email: user.profile.email || '',
        authTime: user.profile.auth_time || +new Date(),
        roles: (user.profile.roles as Array<string>) || [],
      };
      // 开启静默刷新,清除过期状态
      this.oidc.startSilentRenew();
      this.oidc.clearStaleState();
    });
    // 当更新 token 失败时,退出登录
    this.oidc.events.addSilentRenewError(() => {
      this.logout();
    });
    // 当 token 过期时,退出登录
    this.oidc.events.addAccessTokenExpired(() => {
      this.logout();
    });
    // 初始化时加载用户信息
    this.loadUser();
  }
  /**
   * 加载用户信息
   */
  async loadUser() {
    const user = await this.oidc.getUser();
    // 如果能加载出来则将信息放到 Ref 里
    if (user) {
      this.accessToken.value = user.access_token;
      this.userInfo.value = {
        userId: user.profile.sub,
        username: user.profile.preferred_username || '',
        token: user.access_token,
        lastName: '',
        firstName: '',
        email: user.profile.email || '',
        authTime: user.profile.auth_time || +new Date(),
        roles: (user.profile.roles as Array<string>) || [],
      };
      this.oidc.startSilentRenew();
      this.oidc.clearStaleState();
    }
  }
  /**
   * 登录
   */
  login() {
    return this.oidc.signinRedirect();
  }
  /**
   * 检查是否已登录
   * @returns 是否已登录
   */
  async checkLogin(): Promise<boolean> {
    const user = await this.oidc.getUser();
    return user != null && !user.expired;
  }
  /**
   * 退出登录
   */
  logout() {
    this.oidc.stopSilentRenew();
    this.accessToken.value = '';
    this.userInfo.value = undefined;
    return this.oidc.signoutRedirect();
  }
  /**
   * 刷新 token
   * @param force 是否强制刷新
   */
  async refresh(force?: boolean) {
    // 如果不是强制刷新,则先检查用户可用,如果用户可用则不刷新
    if (!force) {
      const user = await this.oidc.getUser();
      if (user != null && !user.expired) {
        return user;
      }
    }
    return this.oidc.signinSilent();
  }
  /**
   * 登录回调
   */
  loginCallback() {
    return this.oidc.signinCallback();
  }
  /**
   * 重置密码
   */
  resetPassword() {
    // 这里使用 keycloak 登录流中的更新密码流实现
    this.oidc.signinRedirect({
      scope: 'openid',
      extraQueryParams: {
        // 这里设置额外参数时,带上 keycloak 的更新密码流
        kc_action: 'UPDATE_PASSWORD',
      },
    });
  }
}

/**
 * 认证插件
 */
const authPlugin: Plugin<UserManagerSettings> = {
  install: (app, options) => {
    const auth = new AuthManager(options);
    app.provide(PROVIDE_KEY, auth);
  },
};

/**
 * 使用认证管理器
 * @returns 认证管理器
 */
const useAuthManager = () => {
  return inject<AuthManager>(PROVIDE_KEY);
};

export { authPlugin, useAuthManager };

到了这里,关于使用 Vue 3 插件(Plugin)实现 OIDC 登录和修改密码(OIDC 系统以 Keycloak 为例)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue项目登录页面实现记住用户名和密码

    记录一下实现的逻辑,应该分两步来理解这个逻辑 首次登录,页面没有用户的登录信息,实现逻辑如下: 用户输入用户名和密码登录,用户信息为名为form的响应式对象,v-model分别对应两个输入框 用户点击登录实现登录功能 判断是否勾选了记住密码,v-model一个CheckBox,勾选

    2024年02月15日
    浏览(31)
  • 路由器登录密码怎么修改 路由器默认出厂登录密码修改教程

    如果路由器当前的管理密码是默认出厂密码,那么将存在风险,因为已经发现黑客利用此漏洞篡改大量路由器设置,因此笔者建议大家还没有修改默认登录密码的朋友,请尽快修改一下路由器默认出厂密码,对于不知道如何修改密码的朋友,以下笔者为大家分享下路由器默认

    2024年02月06日
    浏览(29)
  • C#窗体程序连接SQL Server数据库实现账号登录、账号注册、修改密码、账号注销和实名认证(不定时更新)

    这是本人用Visual Studio2019做的一个C#窗体登录程序,如标题所示,它包含了账号登录、注册账号、修改密码、注销账号和实名认证五个功能。对于有一定基础知识的小伙伴来说,应该不算太难,里面有注释说明,可能咋一看感觉代码运行的逻辑有点乱,不过没关系,相信对你会

    2024年02月02日
    浏览(55)
  • Vue-插件(plugin)

    插件是vue中特别强大并且特别简单的一个东西,它可以帮助我们增强vue 插件本质来说就是一个对象,但是这个对象必须包含install(安装)方法,由vue帮助我们调用 只要插件写的足够的好,就可以帮助我们实现很多的功能,提高开发效率,而我们只需要简单的引入并且use下即可

    2024年02月09日
    浏览(22)
  • vue3项目使用pdf.js插件实现:搜索高亮、修改pdf.js显示的页码、向pdf.js传值、控制搜索、处理接口文件流

    官网地址:http://mozilla.github.io/pdf.js/ 中文文档地址:https://gitcode.gitcode.host/docs-cn/pdf.js-docs-cn/print.html PDF.js是基于HTML5技术构建的,用于展示可移植文档格式的文件(PDF),它可以在现代浏览器中使用且无需安装任何第三方插件。 pdf.js主要包含两个库文件 pdf.js:负责API解析 pdf.wor

    2024年02月13日
    浏览(48)
  • 【项目实战】使用Maven插件(jacoco-maven-plugin),实现生成代码覆盖率报告

    jacoco-maven-plugin是一个Maven插件,用于生成代码覆盖率报告。 它可以帮助您了解您的代码中哪些部分已经被测试覆盖,哪些部分需要更多的测试。 注意,jacoco-maven-plugin 需要 Java 1.5 或更高版本才能运行。 要使用jacoco-maven-plugin,需要在Maven项目中添加以下配置:

    2024年02月15日
    浏览(37)
  • MySQL修改登录密码

    适用于可以登录进入mysql数据库,想修改密码或者提示密码过期 ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement 如果忘记密码可以看Linux系统MySQL忘记登录密码-CSDN博客这篇文章 方法一: 方法二: 方法三: 方法四: 如果提示:ERROR 1819 (HY00

    2024年02月02日
    浏览(26)
  • mysql修改登录用户的密码

    1.如果是使用docker里装的mysql 首先使用 [root@localhost /]# docker ps #查看当前正在运行的容器,也会展示容器的id [root@localhost /]# docker exec -it 容器id /bin/bash root@b46d2c5dcd13:/# mysql -u root -p密码 mysqlupdate user set authentication_string = ‘新密码’ where user = ‘‘root’’; mysqlflush privileges; #退

    2024年02月08日
    浏览(32)
  • Linux修改密码成功,却无法登录

    Linux修改密码成功,却无法登录 等保服务器密码过期后,修改密码,登录显示密码错误,后台vnc修改密码后,新密码无法登录 使用passwd修改密码 显示密码修改成功,但是无法登录 查看secure日志 显示: 密码错误超过次数被限制了! 使用如下命令,清除密码错误次数,或者等待

    2024年02月13日
    浏览(30)
  • Ubuntu的SSH安全配置,查看SSH登录日志文件,修改默认端口,UFW配置防火墙,禁止root用户登录,禁用密码登陆,使用RSA私钥登录,使用 Fail2ban 工具,使用两步验证(2FA)

    环境是Ubuntu 22.04 LTS 不出意外会看到很多类似如下的日志 然后可以统计有多少人在暴力破解root密码错误登录,展示错误次数和ip 因为腾讯云还有个默认用户Ubuntu,也可以一起看看,或是查看一下自己其他用户的错误登录 统计有多少暴力猜用户名的 这台才买回来3天就被扫了

    2024年02月14日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包