The login page The home page Access data

Concepts related to permissions

Classification of permissions

The back-end permissions

Fundamentally speaking, the front end is just the display of the view layer. The core of permissions is data changes in the server, so the back end is the key to permissions. The back end permissions can control whether a user can query data, whether to modify data and other operations

  1. How does the back end know which user sent the request

    cookie session token

  2. Backend permission design RBAC

    User Role Rights

Meaning of front-end permissions

If only from the level of being able to modify the data in the database in the server, it is really enough to control only the back-end, then why more and more projects also carry out front-end permissions control, mainly with these aspects of the benefits

  1. Reduce the possibility of illegal operation, not afraid of stolen goods is afraid of thieves thinking, in the page to show a click on the button will eventually fail, is bound to increase the possibility of illegal operation of intentional people as far as possible to eliminate unnecessary clear, reduce server pressure

  2. Unnecessary request, operation failure of the clear, do not have the authority of the clear, should not need to send at all, less request, naturally will reduce the pressure on the server

  3. Improve the user experience, according to the user has the authority to show the user the content within the scope of their authority, to avoid the user in the interface to bring trouble, let the user focus on their duty

Front – end permission control

Menu control

In the login request, you get permission data, which of course needs to be supported by the backend return data. The front end displays corresponding menus based on permission data. Click the menu to view the relevant interface

Interface control

If the user has not logged in, manually enter the IP address of the management page in the address bar to switch to the login page. If the user has logged in, manually enter the IP address of the management page to switch to the 404 page

Button control

In the interface of a menu, it is necessary to display the buttons that can be operated, such as delete, modify and add, according to the permission data

Request and response control

If a user turns a disabled button on or off through an unusual operation, such as a browser debugger, the request should also be intercepted by the front-end

Implementation steps

Permission menu bar control

After successful login, the user returns a data, including menu list (permissions list returned by the back end) and token. We put this data into VUEX, and then the homepage renders the menu list according to the data in VUEX

login.vue
         //console.log(res.data.rights);
          this.$store.commit('setRightList',res.data.rights)
          this.$store.commit('setUsername',res.data.username)
          this.$message.success('Login successful! ')
           / / cache the token
          window.sessionStorage.setItem('token', res.data.token)
Copy the code
store/index.js

const store = new Vuex.Store({
    state: {
        rightList: JSON.parse(sessionStorage.getItem("rightList") | |'[]'),
        username: sessionStorage.getItem("username")},mutations: {
        setRightList(state, data) {
            state.rightList = data // Here is the point
            sessionStorage.setItem("rightList".JSON.stringify(data))
        },
        setUsername(state, data) {
            state.username = data 
            sessionStorage.setItem("username", data)
        }
    },
    actions: {},
    getters: {}})Copy the code

Symptom: VuEX data disappears and the menu bar disappears

Solution: Store data in sessionStorage and synchronize it with data in VUEX

Interface control

After a successful login, the token data is stored in the sessionStorage to determine whether to log in

1. Route navigation guard

router/index.js

    // Mount the route guard to verify that the token exists
router.beforeEach((to, from, next) = > {
    if (to.path === '/login') return next()
    const tokenStr = window.sessionStorage.getItem('token')
    if(! tokenStr)return next('/login')
    next()
})
Copy the code

Problem: After login, user A can access other pages. However, after login, user A has the permission to access page A, but cannot access page B. However, user A can enter the address bar to access page B because there is A route to page B in the route configuration

Solution: This time we use dynamic routing, to add user permission to the routing configuration dynamic route

2. Dynamic routes

router/index.js
// Define all routing rules first
const usersRule = {
    path: '/users'.component: () = >
        import ('@/components/UserInfo')}const rolesRule = {
    path: '/roles'.component: () = >
        import ('@/components/Roles')}const goodsRule = {
    path: '/goods'.component: () = >
        import ('@/components/Goods')}const categoriesRule = {
    path: '/categories'.component: () = >
        import ('@/components/Categories')}const ruleMapping = {
        'users': usersRule,
        'roles': rolesRule,
        'goods': goodsRule,
        'categories': categoriesRule,
    }
// Dynamically add routes after successful login. Note that the initDynamicRoutes method needs to be exposed and called on the login page
export function initDynamicRoutes() {
    // Dynamically condition routes based on secondary permissions
    const currentRoutes = router.options.routes
    const rightList = store.state.rightList
    rightList.forEach((item) = > {
        item.children.forEach((item_sub) = > {
            const temp = ruleMapping[item_sub.path]
            temp.meta = item_sub.rights
            currentRoutes[2].children.push(temp)
        })
    })
    router.addRoutes(currentRoutes)

}
Copy the code

In this way, if user A enters an inaccessible route in the address bar, the page is not displayed

Problem: If we refresh, the dynamic route will disappear, and the dynamic route is called after the login is successful. The dynamic route was not called during the refresh, so the dynamic route is not added

Create (app.vue); create (app.vue);

App.vue

import {initDynamicRoutes} from '@/router'
export default {
  name: 'App'.created(){
    initDynamicRoutes()
  }
}
Copy the code

3. Button control

Although the user can see some interface, there are some buttons in this interface that the user may not have permission to (add, modify, delete). Therefore, we need to control some buttons in the component, hide or disable buttons that the user does not have permission on, and in this implementation, we can put this logic into custom directives

<template slot-scope="scope">
        <el-button v-permission="{action:'edit',effect:'disabled'}"
          size="mini"
          @click="handleEdit(scope.$index, scope.row)">Modify the</el-button>
        <el-button v-permission="{action:'delete',effect:'disabled'}"
          size="mini"
          type="danger"
          @click="handleDelete(scope.$index, scope.row)">delete</el-button>
      </template>
Copy the code
permission.js

import Vue from "vue"
import router from "@/router"
Vue.directive('permission', {
    inserted(el, binding) {
        const action = binding.value.action
        const effect = binding.value.effect
        if (router.currentRoute.meta.indexOf(action) == -1) {
            if (effect === 'disabled') {
                el.disabled = true
                el.classList.add('is-disabled')}else {
                el.parentNode.removeChild(el)
            }

        }
        // Determine whether the user has the action permission in the component corresponding to the current route}})Copy the code

4. Request and control accordingly

//main.js
// Request interceptor Settings
Vue.prototype.$http = axios
axios.defaults.baseURL = 'http://www.vueadmin.com/admin/'
axios.interceptors.request.use((req) = > {
    console.log(req.url);
    console.log(req.method);
    if(req.url ! = ='login') {
        // req.headers.Authorization = sessionStorage.getItem('token')
        // The logical code is omitted this time
    }
    return req
})

Copy the code

This article is referenced at blog.csdn.net/weixin_4415…