Detailed explanation of Vue identity authentication management and tenant management

Detailed explanation of Vue identity authentication management and tenant management

Overview

The development of functional modules is often the easiest, but it is not easy to handle every detail. Take the identity authentication management module here for example. It seems very simple because the backend interfaces are all ready-made in the ABP template, and the frontend part is nothing more than writing interfaces, calling interfaces, and binding data. However, if you look at the code of the ABP Angular version, you will find that it actually has a lot of details to deal with.

Back to Vue, because there are too many code files in the front-end part, only some details that need attention are listed below. Other things like Vue components, tables, forms, data binding, interface requests, etc. are actually almost the same and will not be mentioned here.

Button-level permissions

In the previous chapter, we implemented the control of menu permissions, and the same principle applies to button permissions. Determine whether abpConfig.auth.grantedPolicies contains a certain permission, and then use v-if rendering in the component.

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>

Identity Authentication Management

I won’t talk about adding, deleting, modifying and checking roles and users, but here we need to pay attention to permission management. Both users and roles need permission management, which is an independent permission-management module in ABP Angular version. I also treat it as a public component here, and distinguish it according to providerName. "R" is role permission and "U" is user permission.

R/U Permissions

There is a slight difference between them. User permissions may come from role permissions, so the permissions in the user need to show which providerName and providerKey they come from. If they come from other providers, they are disabled and cannot be modified.

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;
}

Permission refresh

There is also a detail issue: if the permissions being modified affect the current user, how can they take effect immediately?

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 });
    });
  }
}

There are many things to note, such as the role with isStatic===true cannot be deleted and the name cannot be modified; the password verification rules for adding new users and editing users need to be treated differently; and the save permissions are saved differently. etc. . . If you have the conditions, you can take a look at the Angular code of ABP.

Tenant Management

The basic functional interfaces are similar. . . But there is an option to "manage features", and by default it shows "no features available":

There is no place to add or delete this thing in the interface, but this function is quite practical. It comes from the FeatureManagement module of ABP, also known as "feature management", which will be introduced later.

Tenant Switching

After completing tenant management, you should be able to switch tenants when logging in.

Switching tenants is relatively simple. You just need to obtain the tenant ID based on the entered tenant name, then call the /abp/application-configuration interface and put the tenant ID in the __tenant field of the request Header. This parameter is also required in subsequent requests. If it is not passed, the default host will be used.

In fact, the ABP backend can be configured to enable multi-tenancy. Here, you can also display or hide the tenant switching button according to the backend configuration. Compared with the ABP template, the login interface still lacks a registration entrance, which will be added later.

Effect

at last

The module development of the front-end part will not be introduced in detail, the theme is still ABP. At this point, the front-end functions of the ABP template are almost complete. If you need the code, you can go to https://github.com/xiajingren/HelloAbp to get it. Later, I will organize the files and make a clean vue version.

The above is a detailed explanation of Vue identity authentication management and tenant management. For more information about Vue identity authentication management and tenant management, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • How to implement JWT authentication in Vue routing
  • Complete steps for vue dynamic binding icons
  • Vue custom components use event modifiers to step on the pit record
  • Basic usage examples of Vue named slots
  • Vue Beginner's Guide: Creating the First Vue-cli Scaffolding Program
  • Vue implements left and right sliding effect example code
  • Implementation of communication between Vue and Flask
  • Vue implements two-way data binding
  • Getting Started with Vue 3.0 Custom Directives

<<:  How to mount a disk in Linux

>>:  How to install mysql5.7 in windows

Recommend

About the pitfalls of implementing specified encoding in MySQL

Written in front Environment: MySQL 5.7+, MySQL d...

Implementing simple tabs with js

Tab selection cards are used very frequently on r...

How to solve the slow speed of MySQL Like fuzzy query

Question: Although the index has been created, wh...

JavaScript to make the picture move with the mouse

This article shares the specific code of JavaScri...

A commonplace technique for implementing triangles using CSS (multiple methods)

In some interview experiences, you can often see ...

Detailed explanation of TypeScript 2.0 marked union types

Table of contents Constructing payment methods us...

How to import and export Cookies and Favorites in FireFox

FireFox is a commonly used browser with many exte...

How to use css overflow: hidden (overflow hiding and clearing floats)

Overflow Hide It means hiding text or image infor...

Detailed explanation of Vue's calculated properties

1. What is a calculated attribute? In plain words...

Tutorial on installing MYSQL5.7 from OEL7.6 source code

First, download the installation package from the...

The benefits and examples of placing the site map at the bottom of the web page

In the past, almost every website had a sitemap p...

9 Tips for MySQL Database Optimization

Table of contents 1. Choose the most appropriate ...

Common commands for deploying influxdb and mongo using docker

Deploy database based on docker sudo docker pull ...