详解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如何实现验证码输入交互
Dec 07 Vue.js
Vue实现简单购物车功能
Dec 13 Vue.js
vue 基于abstract 路由模式 实现页面内嵌的示例代码
Dec 14 Vue.js
vue从后台渲染文章列表以及根据id跳转文章详情详解
Dec 14 Vue.js
基于vue+echarts数据可视化大屏展示的实现
Dec 25 Vue.js
Vue 简单实现前端权限控制的示例
Dec 25 Vue.js
vue3弹出层V3Popup实例详解
Jan 04 Vue.js
详解Vue的七种传值方式
Feb 08 Vue.js
vue3中的组件间通信
Mar 31 Vue.js
解读Vue组件注册方式
May 15 Vue.js
教你部署vue项目到docker
Apr 05 Vue.js
vue如何在data中引入图片的正确路径
Jun 05 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的cURL快速入门教程 (小偷采集程序)
2011/06/02 PHP
探讨:array2xml和xml2array以及xml与array的互相转化
2013/06/24 PHP
PNGHandler-借助JS让PNG图在IE下实现透明(包括背景图)
2007/08/31 Javascript
基于mootools插件实现遮罩层新手引导
2012/05/24 Javascript
Jquery弹出层插件ThickBox的使用方法
2014/12/09 Javascript
JavaScript的Polymer框架中dom-repeat与VM的相关操作
2015/07/29 Javascript
Bootstrap被封装的弹层
2016/07/20 Javascript
jQuery EasyUI中的日期控件DateBox修改方法
2016/11/09 Javascript
NodeJS中的MongoDB快速入门详细教程
2016/11/11 NodeJs
适用于手机端的jQuery图片滑块动画
2016/12/09 Javascript
微信小程序 tabs选项卡效果的实现
2017/01/05 Javascript
three.js中文文档学习之创建场景
2017/11/20 Javascript
实例分析JS与Node.js中的事件循环
2017/12/12 Javascript
微信小程序实现顶部下拉菜单栏
2018/11/04 Javascript
详解vuex持久化插件解决浏览器刷新数据消失问题
2019/04/15 Javascript
使用JavaScrip模拟实现仿京东搜索框功能
2019/10/16 Javascript
React 父子组件通信的实现方法
2019/12/05 Javascript
JavaScript实现网页留言板功能
2020/11/23 Javascript
[13:55]Newbee vs Team Spirit
2018/06/07 DOTA
Python数据结构之Array用法实例
2014/10/09 Python
Python算法之图的遍历
2017/11/16 Python
Python排序算法之选择排序定义与用法示例
2018/04/29 Python
Jupyter notebook在mac:linux上的配置和远程访问的方法
2019/01/14 Python
python获取交互式ssh shell的方法
2019/02/14 Python
python关于倒排列的知识点总结
2020/10/13 Python
极简鞋类,赤脚的感觉:Lems Shoes
2019/08/06 全球购物
优秀员工个人的自我评价
2013/11/29 职场文书
幼儿教师寄语集锦
2014/04/03 职场文书
廉洁自律演讲稿
2014/05/22 职场文书
小学班主任培训方案
2014/06/04 职场文书
高三励志标语
2014/06/05 职场文书
师德先进个人材料
2014/12/20 职场文书
幼儿园六一儿童节演讲稿
2015/03/19 职场文书
2015年度内部审计工作总结
2015/05/20 职场文书
mysql联合索引的使用规则
2021/06/23 MySQL
十大动画制作软件,Adobe产品上榜两款,第一是行业标准软件
2022/03/18 杂记