Front-end privilege control of Vue project

Keywords: Vue

Front-end privilege control of Vue project

This paper mainly introduces how to control the front-end privilege in Vue project.

Routing authority

Routing permission means that users can only access the pages they have permission to visit. For pages without permission, they can jump to 404 pages or prompt without permission. There are two ways to realize the right control of routing.

1. Dynamic generation of routing tables

The first way is to dynamically generate the routing table. The original front-end routing table only saves some basic routes. After obtaining the access privileges, a routing table is constructed based on the user's access privileges and added to the routing table dynamically. This ensures that the unauthorized routes are not mounted at all and can not be accessed.

The implementation of this function mainly uses the addRoute method provided by vue-router, which can dynamically add routing to the routing table. Let's look at the implementation.

// router.js
// The front-end routing table retains only the home page and 404 routes.
export default new Router({
  routes: [
    {
      path: '/',
      name: 'Hello',
      component: () => import('@/views/Hello')
    }, {
      path: '*',
      name: '404',
      component: () => import('@/views/404')
    }
  ]
})

// main.js
import router from './router'
// Assume that the user has the following routing privileges
const permission = [{
  name: 'page1',
  children: [{
    name: 'page1_child1'
  }, {
    name: 'page1_child2',
    children: [{
      name: 'page1_child2_child1'
    }]
  }]
}]
// Recursively generate a routing configuration
function createRouteConfigByPermission (permission) {
  let routeConfig = []

  function walk (arr, parent) {
    arr.forEach((item) => {
      let { name, children } = item
      let { name: parentName, path: parentPath, children: parentChildren } = parent
      let path = `${parentPath || ''}/${name}`
      let route = routeFactory({
        path,
        name,
        children,
        parentName
      })
      if (children) {
        walk(children, route)
      }
      if (parentChildren) {
        parent.children.push(route)
      } else {
        parent.push(route)
      }
    })
  }
  walk(permission, routeConfig)
  return routeConfig
}
// The factory function that generates the route includes the attributes of path, name, component, child, etc.
function routeFactory (options = {}) {
  let route = options
  let { name, children, parentName } = route
  parentName = parentName || name
  if (children) {
    route.children = []
  }
  route.component = () => import(`@/views/${parentName}/${name}`)
  return route
}

// Use router.addRoutes to add routing tables
router.addRoutes(createRouteConfigByPermission(permission))

Another idea is to store a complete routing table in the front end, and then filter it according to the privilege information returned by the back end. Call addRoutes to add the filtered routing table. The specific implementation is not detailed here.

2. Global Routing Interception

The second way to control routing privileges is to use global routing interception, that is, to judge the routes to be jumped at each route jump. If users have access privileges, they will successfully jump. Otherwise, they will prompt or jump to the corresponding page.

import router from './router.js'
// User privileges
const permission = {
    '/page1': true,
    '/page1/page1_child1': true
}
router.beforEach((to, from, next) => {
    // The path that jumps is jumped in the permission table
    if (permission.hasOwnProperty(to.path)) {
        next()
    } else {
        // No permission to jump to page 404 or perform other operations
        next('/404')
    }
})

Component permissions

Component permission refers to whether the user has permission to view or operate the components in the page, including buttons, links, etc.

Command control

The way to realize component privilege control is to implement a general hasPermission instruction. The concrete realization is as follows

// User privileges
const permission = {
    '/class/add': true,
    '/class/edit': false
}
Vue.directive('hasPermission', {
    bind: function (el, binding, vnode) {
        if (!permission.hasOwnProperty(binding.value)) {
            el.parentNode.removeChild(el)
            // You can also use display:none
            // el.style.display = 'none'
        }
    }
})
// Use
<template>
    <div>
      <el-button type="primary" v-has-permission="class/add">Add class</el-button>
      <el-button type="primary" v-has-permission="class/edit">Editorial class</el-button>
    </div>
</template>

Last

The front-end privilege control can improve the security of the application and the user's experience, but it can not rely entirely on the front-end, the back-end privilege control is the most critical.

Posted by jwadenpfuhl on Wed, 01 May 2019 09:20:36 -0700