I can't understand the page-level permission management setting process of vue RBAC permissions for you to hammer me

Table of contents

Front

What is RBAC permission design idea

Page-level permission implementation process

analyze

1 Set up routing router/index.js

2 Get permission data filtering to get dynamic routing table

3 The dynamic routing table loads the router and renders the left menu

4 bugs resolved


Front

You need to complete the basic prerequisites of assigning roles to users and assigning permissions to roles, and you can get the user's permission information from the backend/mock.


What is RBAC permission design idea

In layman's terms, if you are a professional chess player ( role ), then you can enter the Chinese Chess Academy ( authority ), although your friend is your friend ( role ), but he is not a professional chess player, the Chinese Chess Academy does not allow outsiders Come in, he can't enter ( permission )

One day, your friend will go crazy, work overtime 24 hours a day, get a professional chess player certification ( role ), and now he can enter the Chinese chess academy ( permission ). 

In short, is it too troublesome if I add permissions to employees one by one? Often companies have a set of rules, role a has permission of type a, role b has permission of b, I want to add permissions to new employees, directly according to the boss Just give him a role

A role is a collection of permissions


Page-level permission implementation process

analyze

First of all, in the routing guard, after logging in, there is a token, enter the else to submit vuex actions to obtain userInfo asynchronously, and the return value of vuex contains permission data

 

1 Set up routing router/index.js

First of all, we know that the page authority is related to the routing router, and the routing table is the key to control whether it can jump to the corresponding page component. Therefore, we need to dynamically set these 8 dynamic routes, according to the menus setting

router/index.js

As you can see, we have written it dead here, so each of our users can access every page, here we directly delete... asyncRoutes

2 Get permission data filtering to get dynamic routing table

Next, we need to establish the connection between the menus returned by the backend and the dynamic routing table. Think about the place where we first get the menus , which is the actions request userInfo submitted by the permission routing guard, which contains the menus . And dispatch returns a promise object , so we can await this value in the route guard

Extension: The return promise object in vuex official website => actions has the required value. You can also directly return the required value here . Because the vuex official website says so首先,你需要明白 store.dispatch 可以处理被触发的 action 的处理函数返回的 Promise,并且 store.dispatch 仍旧返回 Promise:

return value in vuex

Get the value in the routing guard

Print can get the earliest menus in the routing guard

The next thing we have to do here is to take the written dynamic routing table and filter it according to menus to get a new routing table

The object of each of my dynamic routing is like this, you can see that you can use the string after the 2 digits of the path attribute to filter, or you can directly use the name, I use the path to judge

 route guard

const { menus } = await store.dispatch('user/getInfo')
const filterAsyncRoutes = asyncRoutes.filter(item => menus.includes(item.path.slice(1)))

 The dynamic routing table after obtaining the filtering authority

3 The dynamic routing table loads the router and renders the left menu

A new dynamic routing table has been obtained in the routing guard, and there are two things to do next

  1. load to router
  2. Splicing dynamic routing and static routing, rendering the left menu

Here I use vuex to store dynamic and static routes, and then load them into the router, because the menu on the left is other components, and it will be rendered according to the routing table and can be used across components. The specific method is to submit directly after the above routing guards get the required data Mutations, static routing table is imported into vuex, and static and filtered dynamic routing tables are spliced ​​in mutations to generate the final totalRoutes

After the route guard obtains the above value, load the dynamic route to the router immediately. addRoutes method

const { menus } = await store.dispatch('user/getInfo')
const filterAsyncRoutes = asyncRoutes.filter(item => menus.includes(item.path.slice(1)))
router.addRoutes(filterAsyncRoutes)
store.commit('menu/loadRoute', filterAsyncRoutes)

The vuex code routing guard submits mutations, passes the filtered dynamic routing table into the static routing table, and synthesizes the final routing table to render the left menu

Analyze the left menu logic

index.vue of the siderbar component

Originally, this.$router.options.routes is the routing table we configured in router/index.js, and the routing table we dynamically added will not be automatically updated to the routing table, this.$router.options.routes It is to get the routing rules configured during initialization, so this is why I want to save it to vuex by myself. This is also designed by Vue on purpose. The author once answered in issue:options is the object passed to the vuerouter constructor. It's not modified afterwards.

But the author does not recommend using the above method, it is best to save it in vuex

Then the left menu setting change code gets our dynamically set routing table from vuex

The left menu is rendered

4 bugs resolved

bug1: Refresh 404

On the dynamic routing page, such as the department organizational structure above, we can normally access it, but as long as we refresh it, we will find a 404 problem

Because the last rule of our static routing table is *wildcard to 404, when refreshing, the dynamic routing needs to be remounted to the routing instance, but it is intercepted by the wildcard to the 404 page before it is mounted

Solution: 404 is deleted from the static routing table and added to the end of the filtered dynamic routing table, that is, push into the 404 rule

bug2: Refresh blank/page does not load without error

Hey, bug1 has been solved. Did you find another bug? Refreshing the page does not load, does not report an error, and is blank

Why is this? I wondered when I encountered it for the first time. Later, after consulting the information, the probably reason is that we addRoutes in the guard, and we executed next() before it finished executing, so we have to add a next (to.path) Re-enter the guard once, and the dynamic route has been added at this time

bug3: After logging out and logging in again, the console will repeatedly add routes information, and as long as the account without permission does not refresh the page, you can enter the address through the address bar to access the original address without permission

Because we did not reset the route when we logged out, the most serious thing here is permission confusion, because the previous user dynamic routing information has not been cleared, resulting in permission leakage, so reset the route when logging out

Generally, there are three places that need to be set

// router/index.js 定义重置路由方法
export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // reset router
}

// vuex登出actions中 最后重置路由
// 以及一切你知道的问题处 比如token失效时一般我们放到request拦截器里面处理
import { resetRouter } from '@/router'

logout(context) {
      context.commit('updateToken', '')
      context.commit('setUserInfo', {})
      resetRouter()
}

// 我的拦截器中设置当401 status时 提交actions 登出 所以我只用设置上面vuex那段
// 响应拦截器
async error => {
    // console.log('响应拦截器error')
    if (error.response.status === 401) {
      await store.dispatch('user/logout')
      router.push(`/login?redirect=${router.currentRoute.fullPath}`)
    }
    Message.error(error.response.data.message)
    return Promise.reject(error)
}

Bug4: Since we have logged out or the token expires, it will automatically add the path information of the original web page address to the address bar. If we log out and log in to a user who does not have the original web page authority, 404 will appear next(to. path) Add a judgment, if it is not in the menus, directly jump to the home page

menus.includes(to.path.substring(1)) ? next(to.path) : next('/')

menus: The permission array element returned by the backend is the page ID


At this point, basically the page authority management is basically done, have you learned to waste... 

Guess you like

Origin blog.csdn.net/qq_59650449/article/details/128587269