Front end authentication implementation in vue project (menu permission, button permission)

During this period of time, I was busy. I participated in the research and development of a new B-end project of the company. During the process of building the project from scratch, I encountered problems about project authentication. I discussed ideas with my back-end colleagues. I also found information in this regard, which is sorted out as follows

Permission management classification:

1. Menu permission control (page level)

2. Button authority control (button level)

3. Interface permission control (url level)

At present, according to the project requirements, page level and button level permission control are realized.

In terms of implementation id ea, it is very simple. When the user enters the user name and password to log in, the background will return the permission set of the role, and the front end will obtain it and enter it into the local storage. It is recommended to use sessionStorage. When generating the menu, query whether the permission control menu is returned in sessionStorage. The return form can be negotiated from front to back, Menu level permissions are returned according to the menu directory, and button permissions are returned through the list, which can be a set of IDs or a set of special fields. A corresponding mapping table is added to the database.

The following is illustrated with practical examples

First, the user successfully logs in and obtains the permission set from the background. After the interface returns 200, the obtained permission set is stored locally

 // Login succeeded to obtain permission
   window.sessionStorage.setItem('menuList', JSON.stringify(res.data.menuList))
   window.sessionStorage.setItem('permissions', JSON.stringify(res.data.permissions))

Menu permission control

Menu construction

...
<div class="menuContent">
   <Menu :menuList="menuList"></Menu>
</div>
...

The menu components are as follows: they can be modified according to their own defined data format  

<template>
  <div class="menuContent">
    <template v-for="list in menuList">
      <el-submenu v-if="list.children != undefined && list.children.length > 0 && list.show == true" :key="list.title" :index="list.path">
        <template slot="title">
          <!-- <i class="el-icon-menu"></i> -->
          {{ list.title}}
        </template>
        <Menu v-if="list.children != undefined && list.children.length > 0 && list.show == true" :menuList="list.children"></Menu>
      </el-submenu>
      <el-menu-item v-if="(list.children == undefined || list.children.length == 0) && list.show == true" :index="list.path" :key="list.title">
        {{list.title}}
      </el-menu-item>
    </template>
  </div>
</template>

<script>
export default {
  name: 'Menu',
  props: ['menuList'],
  data () {
    return {}
  },
  methods: {
  }
}
</script>
<style lang='scss' scoped>
</style>

  The menu data format is as follows:

menuList: [
        {
          path: '/overview',
          title: 'home page',
          children: [],
          show: ''
        },
        {
          path: '/resource',
          title: 'a page',
          show: '',
          children: [
            {
              path: '/physical',
              title: 'a1 page',
              show: ''
            },
            {
              path: '/logic',
              title: 'a2 page',
              show: ''
            },
            {
              path: '/pool',
              title: 'a3 page',
              show: ''
            }
          ]
        },
        {
          path: '/blockStorage',
          title: 'b page',
          show: '',
          children: [
            {
              path: '/rbdService',
              title: 'b1 page',
              show: ''
            },
            {
              path: '/mapManagement',
              title: 'b2 page',
              show: ''
            },
            {
              path: '/client',
              title: 'b3 page',
              show: ''
            },
            {
              path: '/snapshot',
              title: 'b4 page',
              show: ''
            }
          ]
        },
        {
          path: '/object',
          title: 'c page',
          show: '',
          children: [
            {
              path: '/objectUser',
              title: 'c1 page',
              show: ''
            },
            {
              path: '/bucket',
              title: 'c2 page',
              show: ''
            }
          ]
        }
      ]

Add processing method in menu page js

getMenu () {
      this.menuList.forEach(menu => {
        menu.show = this.hasPermiss(menu.title)
        if (menu.children.length > 0) {
          menu.children.forEach(q => {
            q.show = this.hasPermiss(q.title)
          })
        }
      })
    },
// Determine whether to display the menu by obtaining the menu list in the cache and comparing it
hasPermiss (val) {
      const menuArr = JSON.parse(window.sessionStorage.getItem('menuList'))
      return menuArr.some(item => item.name == val)
      // return true
    }

In the development process, the menuList format configured at the front and rear ends is not unified, so secondary processing is added. If the format is unified, the menu in the local storage can be used directly, so as to realize the permission control of the menu

Button menu control

vue provides user-defined instructions, which can be used to realize button permission control. The core idea remains unchanged. Pass in the permission id / character at the button, and judge whether you have the permission by traversing the cached button permission list

The core method is as follows

import { checkAuthority } from '@/utils/authority'
export default {
  inserted (el, binding, vnode) {
    const { value } = binding
    const permissions = JSON.parse(sessionStorage.getItem('permissions')) || []
    const hasPermission = checkAuthority(value, permissions)
    if (!hasPermission) {
      // eslint-disable-next-line no-unused-expressions
      if (el.parentNode) {
        el.parentNode.removeChild(el)
      } else {
        el.innerHTML = ''
      }
    } else {
      el && el.setAttribute('code', value)
    }
  },
}

  About how to use custom instructions, you can go down and find them yourself. If you write them yourself, you will be more impressed

Tags: Javascript html5 Vue Vue.js

Posted on Fri, 24 Sep 2021 03:33:57 -0400 by cmpennington