Design and implementation of vue permission management

1. What is rights management

Permission management in web applications generally refers to that users can access and only access the resources assigned to them according to the system settings and the application permissions assigned to a certain role. Rights management appears in almost any system, especially in web background management systems.

2. Classification of authority management

  • Backend permissions

    Authority management mainly revolves around data, and the core is the change of data in the server, so the backend is generally the key to authority. The backend tells the frontend what authority the user has, and then the frontend assigns it to the user, so in a long time For a period of time, permissions have always been a topic to be considered by back-end programs. However, with the popularity of the front-end and back-end separation development model, more and more projects are also entering the front-end authority control.

  • Front-end permissions

    In essence, the control of front-end permissions is to control the display of front-end pages and the requests sent by the front-end. But only the front-end permission control must rely on the support of the back-end. Front-end permission control can only be said to achieve the effect of icing on the cake. It can optimize interface logic, simplify project complexity, improve project operation efficiency, reduce server pressure, etc. Therefore, permission control is also an important knowledge point in the front-end.

3. The meaning of front-end permissions

  • Reduce the possibility of illegal operations by users

  • Improve user experience, the menu button without permission is not displayed

  • Intercept unnecessary requests and reduce the pressure on the server

4. Implementation ideas of front-end authority management

Menu control: After the login request is successful, the permission data will be obtained. Of course, this needs to discuss the format of the returned data with the backend. The frontend displays the corresponding menu according to the permission data. Click the menu to view the relevant interface.

Interface control: There are two types of interface control. The first is that the user enters the project address of the non-login page in the address bar before the user logs in. At this time, the access interception should be redirected to the login page. The second is for different users. Some specific pages owned by specific users should not be presented to the user, even if he illegally enters the address he sees. If he enters an illegal address, he should be redirected to the 404 page.

Button control: Different users have different permissions to operate the buttons. The first type of users can only view the data, but cannot change the data. Some users have the function of adding, deleting, modifying and checking the data, so when the same button has no permission, we It should be hidden or disabled for him. The second is that there are multiple tabs on a page, and we should also display them differently according to different permissions.

Control of requests and responses:

Requests and responses beyond user permissions are unnecessary for the system, which will cause unnecessary server overhead and time costs. Such requests and responses need to be controlled so that they cannot be sent at all, such as an editor Button, because there is no permission, the current button is disabled on the page, but if the user opens the console and forcibly sets the disabled attribute of the button to true, users without permission can still operate this button at this time, although it may be in the background It will eventually be intercepted, but the user experience is not very good, so we still need to intercept the currently illegal requests.

5. Dynamic routing (menu-related)

Introduction to dynamic routing: Dynamic is not hard-coded, but variable. We can load the corresponding routes according to the existing permissions. We will not load the routes without permissions to avoid resource waste. It is also an optimization point for the project. The use of dynamic routing is generally used in combination with role permission control.

Advantages of dynamic routing:

  • Security, when the user manually enters an address without permission to enter a certain page, it will be automatically redirected to 404, without us having to control it separately in the routing guard

  • Flexible, you can configure the increase and decrease of the menu, so that you don't have to deal with it every time you modify it. Subsequent menus are added, and the routing is processed uniformly, which is convenient and fast.

6. Function realization

Here I will use a demo as an example. In the demo, the four aspects of menu , interface , button and request will be realized. The demo technology stack is realized by vue2+vue-router+element-ui, and the background data is simulated by mock.js .

Method 1 (without using dynamic routing)

The overall implementation idea here is to assign a unique code to each menu menu and button, and then the background returns the code permission table set of the corresponding role user, and the front end gets the code permission table for screening processing

 There are two user roles in the demo, one is admin (super administrator), which has all the permissions, and the other is test (ordinary administrator), which has some permissions

After the user logs in, the server returns a piece of data, which has the permission code table (permission) and token corresponding to the role

 ​​​​

After we log in successfully, we get the data and store it in vuex first, and then we use it, but we will find a problem. After we refresh the page, the vuex data will disappear.

Reason: The data in vuex is stored in the running memory. When the page is refreshed, the page will reload the vue instance, and the data in vuex will be reassigned to the initial value.

Solution: save the data in localstorage, sessionstorage or cookie (because these are stored in the browser, which is equivalent to storing in the hard disk, if not actively cleared, it will always exist), and keep it in sync with vuex.

  •  Menu control : compare the returned code table with the router object, each router object has a roleCode attribute, representing the current menu menu

 Here we use a method to filter. This method passes in the current code table and all router objects, and finally returns a new routing object that meets the code permissions. The menu initialization on the left is the entire router object, that is, it has all the menu menus , now after filtering, only menu menus with permissions for the current role are returned

 The login is successful and the following menu is obtained by filtering according to the above method

 After this, the menu module looks like it is done, but in fact, if we refresh it, we will find that the menu menu just filtered will be restored to all menus, and the method of filtering menus is invalid.

Reason: The route filtering route is called only after the login is successful, and it is not called when it is refreshed, so the route is not added after the refresh.

Solution: You can call the method of adding a filter menu route in created in app.vue

  • Interface control: Since no dynamic routing method is used, all routes in the project are actually registered, so even if the corresponding menu menu is not displayed on the page, we enter the URL that does not have this permission on the address bar. Address We can still enter this page, so we should control the permissions of the interface next

admin user

test user

 The test user does not have a role to manage the entire module

So we need to add one more step here, which is to intercept in the routing front guard. If it is judged that there is no such permission, it should be redirected to the 404 page.

Solution: Give him a side section in the front guard of the route. If you have permission to let it go, if you don’t have permission, go directly to 404

 Question: I thought this would be all right, but the problem came again. When I tried to access a role module that does not exist for the test user, I entered the address in the address bar, but ended up in an endless loop.

So I checked the information and found that this problem is actually caused by the lack of understanding of the router.beforEach operating mechanism of vue-router

Solution: Based on the whole mechanism, let's modify it

Friendship link: Vue-router infinite loop can refer to this blog https://blog.csdn.net/weixin_45306532/article/details/114434748

 After the above operations are completed, the menu part is really, really, really finished. Enter an illegal address and enter 404

  • Button permissions: Now the user can see some interfaces with permissions, but some buttons and tabs pages of this interface may not have permissions for the user.
  1. Button processing: the button that the user does not have permission is hidden or disabled, and in the implementation of this piece, the logic can be placed in the custom instruction

        a: Create a new permission.js file and register custom instructions

          

         b.main.js introduces permission.js

          

          c. Add a custom instruction on the button, and pass the code corresponding to the current button into the custom instruction

              

     2. Tabs processing: perform tabs filtering in the computed of the current page component

          There is a role attribute in the configuration data of a.tabs, corresponding to the current permission

        

         b. The computed of the user management/user level component is processed

        

After the above operations are completed, the effect of the test user is as follows

test user

admin user 

  • Interface request control: Currently, the interface permission is generally verified in the form of jwt. If it fails, it usually returns 401, jumps to the login page to log in again, gets the token after logging in, saves the token, and intercepts it through the axios request interceptor . The token is carried in the header every time a request is made.

At this point, the button-level control is over.

 Method 2 (using dynamic routing)

This method adds dynamic routing based on the menu authority of the first method

In my router, only the homepage/home, login page/login, and 404 page are reserved, because all users who log in to these pages have permission to view them.

router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import Login from '@/views/login/index.vue'
import Layout from '@/components/Layout.vue'
import NotFound from '@/components/NotFound.vue'
// isShow属性:el-menu树要不要渲染
// isMenuItem:el-menu树有没有字节点
Vue.use(Router)
const router = new Router({
  routes: [
    {
      path: '/',
      redirect: '/home',
      isShow: true,
      authName: '首页',
      isMenuItem: true,
      component: Layout,
      meta: {
        roleCode: 'home'
      },
      children: [
        {
          id: 110,
          meta: {
            roleCode: ''
          },
          authName: '项目权限介绍',
          path: '/home',
          component: (resolve) => require(['@/views/home'], resolve)
        }
      ]
    },
    {
      path: '/login',
      component: Login,
      isShow: false
    },
    {
      isShow: false,
      path: '*',
      component: NotFound
    },
    {
      isShow: false,
      path: '/404',
      component: NotFound
    }
  ]
})
// 筛选有权限的菜单
export function filterRoute(arr, arr1) {
  const realRoutes = []
  arr.forEach((v) => {
    // console.log(v, 'vvv')
    if (!v.meta.roleCode) {
      realRoutes.push(v)
    }
    arr1.forEach(item => {
      if (item === v.meta.roleCode) {
        if (v.children && v.children.length > 0) {
          v.children = filterRoute(v.children, arr1)
        }
        realRoutes.push(v)
      }
    })
  })
  return realRoutes
};

router.beforeEach((to, from, next) => {
  console.log(router.options.routes, 'over111')
  if (to.path === '/login') {
    next()
  } else {
    const token = sessionStorage.getItem('token')
    if (!token) {
      next('/login')
    } else {
      // 筛选权限
      next()
    }
  }
})
export default router

In addition, I put all the routers in another js file for judging the permissions, and dynamically register those with permissions to enter the router routing object.

router/routingArray.js


import Layout from '@/components/Layout.vue'
const router = [
  {
    id: 125,
    authName: '用户管理',
    path: '/User',
    name: 'User',
    redirect: '/User/Userlist',
    icon: 'icon-user',
    meta: {
      roleCode: 'user'
    },
    isMenuItem: false,
    isShow: true,
    component: Layout,
    children: [
      {
        id: 110,
        isMenuItem: true,
        meta: {
          roleCode: 'userlist'
        },
        authName: '用户列表',
        path: '/User/Userlist',
        name: 'Userlist',
        component: (resolve) => require(['@/views/user/userlist.vue'], resolve)
      },
      {
        id: 120,
        isMenuItem: true,
        meta: {
          roleCode: 'usergrade'
        },
        authName: '用户等级',
        path: '/User/Usergrade',
        component: (resolve) => require(['@/views/user/usergrade.vue'], resolve)
      }
    ]
  },
  {
    isShow: true,
    isMenuItem: false,
    id: 103,
    path: '/Roles',
    name: 'Roles',
    meta: {
      roleCode: 'roles'
    },
    authName: '角色管理',
    redirect: '/Roleslist',
    icon: 'icon-tijikongjian',
    component: Layout,
    children: [
      {
        id: 111,
        isShow: true,
        isMenuItem: true,
        meta: {
          roleCode: 'roleslist'
        },
        authName: '角色列表',
        path: '/Roleslist',
        component: (resolve) => require(['@/views/role/rolelist.vue'], resolve)
      }
    ]
  }
]

export default router

 Do processing after successful login

 Note: After vue-router4.x version, router.addRoutes has been abandoned, and the official has been changed to outer.addRoute, and multiple dynamic injections need to be injected sequentially in a loop.

After refreshing, the same as method 1, call the method of adding filter menu routing in created in app.vue to avoid refresh invalidation

 This is the end of the introduction of the second method, the page, button , request and response permissions are the same as the first method.

Seven: template exercise

The demo template has been uploaded to the code cloud last time. Those who need it can get it by themselves. It is not easy to make it. Please click a free star and hold your fists. If there is not enough, you are welcome to add it.

Vue permission management demo: Vue permission management demo, if there are any deficiencies, welcome to add, fists up

Guess you like

Origin blog.csdn.net/weixin_40565812/article/details/130509188