Implementation of iview permission management

Implementation of iview permission management

iview-admin2.0 built-in permission management

iview-admin2.0 comes with permission management, and permissions can be assigned by setting the access parameter of the routing meta object.
The default roles are super_admin and admin. Now we assign a permission that only user can view to the document sidebar item.

  {
    path: '',
    name: 'doc',
    meta: {
      title: 'Document',
      href: 'https://lison16.github.io/iview-admin-doc/#/',
      icon: 'ios-book',
      access: ['user']
    }
  },

The Documents column will no longer be displayed in the sidebar. Get menuList in src/store/module/app.js, this is the list of the sidebar

  getters: {
    menuList: (state, getters, rootState) => getMenuByRouter(routers, rootState.user.access),
    errorCount: state => state.errorList.length
  },

This getter method mainly executes getMenuByRouter, then check src/libs/util.js to find the specific code

/**
 * @param {Array} list Get the menu list through the route list * @returns {Array}
 */
export const getMenuByRouter = (list, access) => {
  let res = []
  forEach(list, item => {
    if (!item.meta || (item.meta && !item.meta.hideInMenu)) {
      let obj = {
        icon: (item.meta && item.meta.icon) || '',
        name: item.name,
        meta: item.meta
      }
      if ((hasChild(item) || (item.meta && item.meta.showAlways)) && showThisMenuEle(item, access)) {
        obj.children = getMenuByRouter(item.children, access)
      }
      if (item.meta && item.meta.href) obj.href = item.meta.href
      if (showThisMenuEle(item, access)) res.push(obj)
    }
  })
  return res
}
const showThisMenuEle = (item, access) => {
  if (item.meta && item.meta.access && item.meta.access.length) {
    if (hasOneOf(item.meta.access, access)) return true
    else return false
  } else return true
}

At this point, the process of access determining permissions is clearer. The code will obtain the user information stored in the state, mainly access, and then compare it with the access allowed by the route. If the user's access is within the range allowed by the route access list, the right is confirmed. For example, the user access is ['admin', 'super_admin'], but we set the document access to ['user'].

hasOneOf(['admin','super_admin'],['user']) // false, authentication failed

hasOneOf is a tool method of iview-admin. Used to determine whether at least one element of the array to be queried is contained in the target array. The detailed code is at the bottom.

Control component display based on permissions

Generally, we also need to control the display of page elements, such as buttons, based on permissions. There are two ways. One is to customize the auth instruction, or customize an authentication component to wrap the elements that need authentication.

Custom auth directives

iview-admin puts custom directives in the src/directive folder. The directives.js file is responsible for importing custom directives defined in each file and exporting them uniformly. We implement an auth directive:

import draggable from './module/draggable'
import clipboard from './module/clipboard'
import auth from './module/auth'
const directives = {
  draggable,
  clipboard,
  auth
}
export default directives

Then an importDirective method is exported in src/directive/index.js, the input parameter is Vue, and the logic is to register the directive.

import directive from './directives'

const importDirective = Vue => {
  /**
   * Drag command v-draggable="options"
   * options = {
   * trigger: /pass in the CSS selector as the drag trigger/,
   * body: /pass in the CSS selector of the container to be moved/,
   * recover: /Whether to restore to the original position after dragging ends/
   * }
   */
  Vue.directive('draggable', directive.draggable)
  /**
   * Clipboard directive v-draggable="options"
   * options = {
   * value: /value bound to v-model in the input box/,
   * success: /Callback after successful copying/,
   * error: /Callback after copy failure/
   * }
   */
  Vue.directive('clipboard', directive.clipboard)
  Vue.directive('auth', directive.auth) 
}

export default importDirective

This importDirective method is used in main.js, and the real Vue is passed in as an input parameter.

import importDirective from '@/directive'
/**
 * Registration instructions */
importDirective(Vue)
...

Edit src/directive/module/auth.js

import store from '@/store'
export default {
  inserted: (el, binding, vnode) => {
    const value = binding.value
    const access = store.state.user.access
    if (access.indexOf(value) === -1) {
      el.remove()
    }
  }
}

We add an auth directive and export it. Perform permission check during injection. If the permission is confirmed successfully, do nothing. If it fails, delete the element.
Try it out, take the top collapse menu button as an example, beader-bar.vue

<template>
  <div class="header-bar">
    <sider-trigger v-auth="'admin'" :collapsed="collapsed" icon="md-menu" @on-change="handleCollpasedChange"></sider-trigger>
    ...
  </div>
</template>

When v-auth="'admin'", the button is displayed, and if it is user, the button is hidden.

Custom auth component

You can also customize the auth component and create a functional component auth.vue

<script>
import store from '@/store'
export default {
  functional: true,
  props: {
    authority:
      type: String,
      require: true
    }
  },
  render (h, context) {
    const { props, scopedSlots } = context
    const access = store.state.user.access
    return access.indexOf(props.authority) > -1 ? scopedSlots.default() : null
  }
}
</script>

If the authentication is successful, slot is returned, otherwise null is returned, so that the element wrapped by auth will not be displayed. Then register auth.vue as a global component to avoid having to import it every time you use it. Edit main.js

import Auth from '_c/auth/auth.vue'
// Register component Vue.component('Auth',Auth)

When using it, just wrap the component with auth

<template>
  <div class="header-bar">
    <Auth authority="user">
      <sider-trigger :collapsed="collapsed" icon="md-menu" @on-change="handleCollpasedChange"></sider-trigger>
    </Auth>
  </div>
</template>

Summarize

It can be implemented using either component-based writing or custom instructions. The component-based approach requires more code to write, and custom instructions are more flexible. In addition, there is one difference. If the custom instruction fails to confirm the right, the element is directly deleted. Therefore, if you change from admin to user at this time, the element will still not be displayed, because it has been deleted. You need to refresh the page to display it, but if it is a component-based approach, it will not happen and can respond flexibly. This generally has little impact.

Note that I set access to a string. If you set it to an array, it will also work. The hasOneOf method that comes with iview can be used well.

/**
 * @param {Array} target target array* @param {Array} arr array to be queried* @description Determine whether at least one element of the array to be queried is contained in the target array*/
export const hasOneOf = (targetarr, arr) => {
  return targetarr.some(_ => arr.indexOf(_) > -1)
}

This is the end of this article about the implementation of iview permission management. For more relevant iview permission management content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of Vue.js iview to implement tree-shaped permission table (extensible table)
  • Vue iview implements dynamic routing and permission verification functions

<<:  How to manually upgrade the kernel in deepin linux

>>:  Analysis of problems caused by MySQL case sensitivity

Recommend

Steps to create a Vite project

Table of contents Preface What does yarn create d...

Vue keeps the user logged in (various token storage methods)

Table of contents How to set cookies Disadvantage...

MySQL/MariaDB Root Password Reset Tutorial

Preface Forgotten passwords are a problem we ofte...

7 interview questions about JS this, how many can you answer correctly

Preface In JavaScript, this is the function calli...

Summary of 16 XHTML1.0 and HTML Compatibility Guidelines

1. Avoid declaring the page as XML type . The pag...

Native js to achieve seamless carousel effect

Native js realizes the carousel effect (seamless ...

MySQL 5.7.21 installation and configuration tutorial under Window10

This article records the installation and configu...

Analysis of the Neglected DOCTYPE Description

doctype is one of them: <!DOCTYPE HTML PUBLIC &...

About Vue's 4 auxiliary functions of Vuex

Table of contents 1. Auxiliary functions 2. Examp...

Knowledge about MySQL Memory storage engine

Knowledge points about Memory storage engine The ...