详解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中使用kindeditor富文本编辑器
Dec 19 Vue.js
为什么推荐使用JSX开发Vue3
Dec 28 Vue.js
vue3中轻松实现switch功能组件的全过程
Jan 07 Vue.js
如何在Vue项目中添加接口监听遮罩
Jan 25 Vue.js
vue穿梭框实现上下移动
Jan 29 Vue.js
vue 数据双向绑定的实现方法
Mar 04 Vue.js
如何理解Vue前后端数据交互与显示
May 10 Vue.js
Vue3中的Refs和Ref详情
Nov 11 Vue.js
Vue的过滤器你真了解吗
Feb 24 Vue.js
在vue中import()语法不能传入变量的问题及解决
Apr 01 Vue.js
vue项目proxyTable配置和部署服务器
Apr 14 Vue.js
vue ant design 封装弹窗表单的使用
Jun 01 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
DISCUZ在win2003环境下 Unable to access ./include/common.inc.php in... 的问题终极解决方案
2011/11/21 PHP
PHP中strtotime函数使用方法详解
2011/11/27 PHP
phpize的深入理解
2013/06/03 PHP
PHP Echo字符串的连接格式
2016/03/07 PHP
PHP简单读取xml文件的方法示例
2017/04/20 PHP
Yii2框架redis基本应用示例
2018/07/13 PHP
php对微信支付回调处理的方法
2018/08/23 PHP
jquery 问答知识整理
2010/02/11 Javascript
一起来写段JS drag拖动代码
2010/12/09 Javascript
jquery foreach使用示例
2013/09/12 Javascript
JS中的数组的sort方法使用示例
2014/01/22 Javascript
javascript实现图片自动和可控的轮播切换特效
2015/04/13 Javascript
超赞的动手创建JavaScript框架的详细教程
2015/06/30 Javascript
JavaScript实现iframe自动高度调整和不同主域名跨域
2016/02/27 Javascript
让你彻底掌握es6 Promise的八段代码
2017/07/26 Javascript
利用babel将es6语法转es5的简单示例
2017/12/01 Javascript
nodejs超出最大的调用栈错误问题
2017/12/27 NodeJs
vuex存储复杂参数(如对象数组等)刷新数据丢失的解决方法
2019/11/05 Javascript
JavaScript常用工具函数汇总(浏览器环境)
2020/09/17 Javascript
Openlayers测量距离与面积的实现方法
2020/09/25 Javascript
利用js canvas实现五子棋游戏
2020/10/11 Javascript
vue单元格多列合并的实现
2020/11/26 Vue.js
python实现DNS正向查询、反向查询的例子
2014/04/25 Python
跟老齐学Python之玩转字符串(2)更新篇
2014/09/28 Python
Python 2与Python 3版本和编码的对比
2017/02/14 Python
R vs. Python 数据分析中谁与争锋?
2017/10/18 Python
浅谈Python2、Python3相对路径、绝对路径导入方法
2018/06/22 Python
Python Grid使用和布局详解
2018/06/30 Python
树莓派与PC端在局域网内运用python实现即时通讯
2019/06/22 Python
python已协程方式处理任务实现过程
2019/12/27 Python
Keras 中Leaky ReLU等高级激活函数的用法
2020/07/05 Python
法国在线购买汽车轮胎网站:123pneus.fr
2019/02/25 全球购物
食品安全责任书
2014/04/15 职场文书
酒店财务经理岗位职责
2015/04/08 职场文书
2015年政务公开工作总结
2015/05/19 职场文书
浅谈redis五大数据结构和使用场景
2021/04/12 Redis