详解vue身份认证管理和租户管理


Posted in Vue.js onMay 25, 2021

概述

功能模块的开发往往是最容易的,但是要处理好每个细节就不容易了。就拿这里的身份认证管理模块来说,看似很简单,因为后端接口都是ABP模板里现成的,前端部分无非就是写界面,调接口,绑数据;但是看一下ABP Angular版本的代码,就会发现他其实是有很多细节方面的处理的。

回到vue,因为前端部分的代码文件太多,下面只列出一些需要注意的细节,其他的像vue组件、表格、表单、数据绑定、接口请求之类的其实都差不多就不说了。

按钮级权限

前面章节中实现了菜单权限的控制,按钮权限的道理也是一样的。判断abpConfig.auth.grantedPolicies是否包含某个权限,然后在组件中使用v-if渲染就好了。

src\utils\abp.js:

export function checkPermission(policy) {
  const abpConfig = store.getters.abpConfig;
  if (abpConfig.auth.grantedPolicies[policy]) {
    return true;
  } else {
    return false;
  }
}

src\views\identity\roles.vue:

<el-button
  class="filter-item"
  style="margin-left: 10px;"
  type="primary"
  icon="el-icon-edit"
  @click="handleCreate"
  v-if="checkPermission('AbpIdentity.Roles.Create')"
>
  {{ $t("AbpIdentity['NewRole']") }}
</el-button>

详解vue身份认证管理和租户管理

详解vue身份认证管理和租户管理

身份认证管理

角色和用户的增删改查就不说了,这里要注意一下权限管理。用户和角色都需要用到权限管理,在ABP Angular版中是一个独立的permission-management模块。我这里也把他作为一个公用组件,根据providerName来区分,"R"是角色权限,"U"是用户权限。

R/U权限

他们有一点区别,用户权限可能来自于角色权限,所以用户中的权限需要显示是来自哪个providerName和providerKey,如果来自其他provider则disabled,不可以修改。

src\views\identity\components\permission-management.vue:

<el-form label-position="top">
  <el-tabs tab-position="left">
    <el-tab-pane
      v-for="group in permissionData.groups"
      :key="group.name"
      :label="group.displayName"
    >
      <el-form-item :label="group.displayName">
        <el-tree
          ref="permissionTree"
          :data="transformPermissionTree(group.permissions)"
          :props="treeDefaultProps"
          show-checkbox
          check-strictly
          node-key="name"
          default-expand-all
        />
      </el-form-item>
    </el-tab-pane>
  </el-tabs>
</el-form>
transformPermissionTree(permissions, name = null) {
  let arr = [];
  if (!permissions || !permissions.some(v => v.parentName == name))
    return arr;
  const parents = permissions.filter(v => v.parentName == name);
  for (let i in parents) {
    let label = '';
    if (this.permissionsQuery.providerName == "R") {
      label = parents[i].displayName;
    } else if (this.permissionsQuery.providerName == "U") {
      label =
        parents[i].displayName +
        " " +
        parents[i].grantedProviders.map(provider => {
          return `${provider.providerName}: ${provider.providerKey}`;
        });
    }
    arr.push({
      name: parents[i].name,
      label,
      disabled: this.isGrantedByOtherProviderName(
        parents[i].grantedProviders
      ),
      children: this.transformPermissionTree(permissions, parents[i].name)
    });
  }
  return arr;
},
isGrantedByOtherProviderName(grantedProviders) {
  if (grantedProviders.length) {
    return (
      grantedProviders.findIndex(
        p => p.providerName !== this.permissionsQuery.providerName
      ) > -1
    );
  }
  return false;
}

详解vue身份认证管理和租户管理

详解vue身份认证管理和租户管理

权限刷新

还有一个细节问题,如果正在修改的权限影响到了当前用户,如何立即生效。

src\views\identity\components\permission-management.vue:

updatePermissions(this.permissionsQuery, { permissions: tempData }).then(
  () => {
    this.dialogPermissionFormVisible = false;
    this.$notify({
      title: this.$i18n.t("HelloAbp['Success']"),
      message: this.$i18n.t("HelloAbp['SuccessMessage']"),
      type: "success",
      duration: 2000
    });
    fetchAppConfig(
      this.permissionsQuery.providerKey,
      this.permissionsQuery.providerName
    );
  }
);

src\utils\abp.js:

function shouldFetchAppConfig(providerKey, providerName) {
  const currentUser = store.getters.abpConfig.currentUser;

  if (providerName === "R")
    return currentUser.roles.some(role => role === providerKey);

  if (providerName === "U") return currentUser.id === providerKey;

  return false;
}
export function fetchAppConfig(providerKey, providerName) {
  if (shouldFetchAppConfig(providerKey, providerName)) {
    store.dispatch("app/applicationConfiguration").then(abpConfig => {
      resetRouter();

      store.dispatch("user/setRoles", abpConfig.currentUser.roles);

      const grantedPolicies = abpConfig.auth.grantedPolicies;

      // generate accessible routes map based on grantedPolicies
      store
        .dispatch("permission/generateRoutes", grantedPolicies)
        .then(accessRoutes => {
          // dynamically add accessible routes
          router.addRoutes(accessRoutes);
        });

      // reset visited views and cached views
      //store.dispatch("tagsView/delAllViews", null, { root: true });
    });
  }
}

详解vue身份认证管理和租户管理

还有很多需要注意的,比如isStatic===true的角色不可以删除,并且不可以修改名称;新增用户和编辑用户的密码校验规则需要区别对待;保存权限是差异保存。等等。。。有条件的可以看一下ABP的Angular代码。

租户管理

基本功能界面都差不多。。。但是这里有一个”管理功能“的选项,默认是显示”没有可用的功能“:

详解vue身份认证管理和租户管理

这玩意在界面上没地方添加,也没地方删除,但是这个功能相当实用。它来自ABP的FeatureManagement模块,也称为”特征管理“,这个后面再做介绍。

租户切换

完成了租户管理,那么登录时也应该可以切换租户。

详解vue身份认证管理和租户管理

切换租户比较简单,就是根据输入的租户名称获取到租户ID,然后调用/abp/application-configuration接口,把租户ID放到请求Header的__tenant字段中即可,之后的请求中也需要这个参数,不传的话就是默认的宿主端。

详解vue身份认证管理和租户管理

其实ABP后端是可以配置是否启用多租户的,这里也可以根据后端配置来显示或者隐藏租户切换的按钮。跟ABP模板相比,登录界面还缺少一个注册入口,后面再加上吧。

效果

详解vue身份认证管理和租户管理

详解vue身份认证管理和租户管理

详解vue身份认证管理和租户管理

详解vue身份认证管理和租户管理

详解vue身份认证管理和租户管理

最后

前端部分的模块开发就不再详细介绍了,主题还是ABP。进行到这里,ABP模板自带的前端部分功能就差不多完成了,需要代码的可以去 https://github.com/xiajingren/HelloAbp 拉取,后面我再把文件整理一下,弄一个干净的vue版本。

以上就是详解vue身份认证管理和租户管理的详细内容,更多关于vue身份认证管理和租户管理的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
vue中echarts的用法及与elementui-select的协同绑定操作
Nov 17 Vue.js
vue 表单输入框不支持focus及blur事件的解决方案
Nov 17 Vue.js
详解Vue的mixin策略
Nov 19 Vue.js
vue自定义插件封装,实现简易的elementUi的Message和MessageBox的示例
Nov 20 Vue.js
浅析VUE防抖与节流
Nov 24 Vue.js
Vue组件生命周期运行原理解析
Nov 25 Vue.js
Vue+penlayers实现多边形绘制及展示
Dec 24 Vue.js
Vue+scss白天和夜间模式切换功能的实现方法
Jan 05 Vue.js
vue实现验证用户名是否可用
Jan 20 Vue.js
vue 组件基础知识总结
Jan 26 Vue.js
vue+flask实现视频合成功能(拖拽上传)
Mar 04 Vue.js
vue二维数组循环嵌套方式 循环数组、循环嵌套数组
Apr 24 Vue.js
vue点击弹窗自动触发点击事件的解决办法(模拟场景)
vue-element-admin项目导入和导出的实现
May 21 #Vue.js
vue2实现provide inject传递响应式
May 21 #Vue.js
vue使用节流函数的踩坑实例指南
vue实现同时设置多个倒计时
May 20 #Vue.js
Vue和Flask通信的实现
Vue Element UI自定义描述列表组件
You might like
PHP CKEditor 上传图片实现代码
2009/11/06 PHP
PHP合并静态文件详解
2014/11/14 PHP
php实现贪吃蛇小游戏
2016/07/26 PHP
PHP发送邮件确认验证注册功能示例【修改别人邮件类】
2019/11/09 PHP
javascript URL编码和解码使用说明
2010/04/12 Javascript
本地对象Array的原型扩展实现代码
2010/12/04 Javascript
jquery实现表格奇数偶数行不同样式(有图为证及实现代码)
2013/01/23 Javascript
现代 JavaScript 开发编程风格Idiomatic.js指南中文版
2014/05/28 Javascript
JS实现点击按钮后框架内载入不同网页的方法
2015/05/05 Javascript
javascript 判断两个日期之差的示例代码
2015/09/05 Javascript
javascript新闻跑马灯实例代码
2020/07/29 Javascript
JavaScript中0和&quot;&quot;比较引发的问题
2016/05/26 Javascript
AngularJS创建自定义指令的方法详解
2016/11/03 Javascript
vue服务端渲染的实例代码
2017/08/28 Javascript
Vue项目组件化工程开发实践方案
2018/01/09 Javascript
Angular动态绑定样式及改变UI框架样式的方法小结
2018/09/03 Javascript
解决layui 三级联动下拉框更新时回显的问题
2019/09/03 Javascript
Vue3为什么这么快
2020/09/23 Javascript
[02:01]BBC DOTA2国际邀请赛每日综述:八强胜者组鏖战,中国队喜忧参半
2014/07/19 DOTA
详解Python的Django框架中的Cookie相关处理
2015/07/22 Python
Python编程实战之Oracle数据库操作示例
2017/06/21 Python
浅谈python和C语言混编的几种方式(推荐)
2017/09/27 Python
基于Django的ModelForm组件(详解)
2017/12/07 Python
Tensorflow实现酸奶销量预测分析
2019/07/19 Python
Python之虚拟环境virtualenv,pipreqs生成项目依赖第三方包的方法
2019/07/23 Python
Python实现自定义读写分离代码实例
2019/11/16 Python
python实现while循环打印星星的四种形状
2019/11/23 Python
python3获取控制台输入的数据的具体实例
2020/08/16 Python
python3 os进行嵌套操作的实例讲解
2020/11/19 Python
Html5实现如何在两个div元素之间拖放图像
2013/03/29 HTML / CSS
李维斯法国官网:Levi’s法国
2019/07/13 全球购物
植树造林的宣传标语
2014/06/23 职场文书
公司会议开幕词
2015/01/29 职场文书
毕业实习证明范本
2015/06/16 职场文书
何时使用Map来代替普通的JS对象
2021/04/29 Javascript
分位数回归模型quantile regeression应用详解及示例教程
2021/11/02 Python