vue 權限管理怎么做


前言

在一個項目中,一些功能會涉及到重要的數據管理,為了確保數據的安全,我們會在項目中加入權限來限制每個用戶的操作。作為前端,我們要做的是配合后端給到的權限數據,做頁面上的各種各樣的限制。

需求

因為這是一個工作上的業務需求,所以對於我來說主要有兩個地方需要進行權限控制。

第一個是側邊菜單欄,需要控制顯示與隱藏。

第二個就是頁面內的各個按鈕,彈窗等。

流程

  1. 如何獲取用戶權限?

    后端(當前用戶擁有的權限列表)-> 前端(通過后端的接口獲取到,下文中我們把當前用戶的權限列表叫做 permissionList)

  2. 前端如何做限制?

    通過產品的需求,在項目中進行權限點的配置,然后通過 permissionList 尋找是否有配置的權限點,有就顯示,沒有就不顯示。

  3. 然后呢?

    沒了。

當我剛開始接到這個需求的時候就是這么想的,這有什么難的,不就獲取 permissionList 然后判斷就可以了嘛。后來我才發現真正的需求遠比我想象的復雜。

真正的問題

上面的需求有提到我們主要解決兩個問題,側邊菜單欄的顯示 & 頁面內操作。

假設我們有這樣一個路由的設置(以下只是一個例子):

import VueRouter from  vue-router

/* 注意:以下配置僅為部分配置,並且省去了 component 的配置 */

export const routes = [

  {

    path:  / ,

    name:  Admin ,

    label:  首頁

  },

  {

    path:  /user ,

    name:  User ,

    label:  用戶 ,

    redirect: { name:  UserList  },

    children: [

      {

        path:  list ,

        name:  UserList ,

        label:  用戶列表

      },

      {

        path:  group ,

        name:  UserGroup ,

        label:  用戶組 ,

        redirect: { name:  UserGroupList  },

        children: [

          {

            path:  list ,

            name:  UserGroupList ,

            label:  用戶組列表

          },

          {

            path:  config ,

            name:  UserGroupConfig ,

            label:  用戶組設置

          }

        ]

      }

    ]

  },

  {

    path:  /setting ,

    name:  Setting ,

    label:  系統設置

  },

  {

    path:  /login ,

    name:  Login ,

    label:  登錄

  }

]

 

const router = new VueRouter({

  routes

})

 

export default router

其中前兩級路由會顯示在側邊欄中,第三級就不會顯示在側邊欄中了。

頁面內操作的權限設置不需要考慮很多其他東西,我們主要針對側邊欄以及路由進行問題的分析,通過分析,主要有以下幾個問題:

  1. 什么時候獲取 permissionList,如何存儲 permissionList

  2. 子路由全都沒權限時不應該顯示本身(例:當用戶列表和用戶組都沒有權限時,用戶也不應該顯示在側邊欄)

  3. 默認重定向的路由沒有權限時,應尋找 children 中有權限的一項重定向(例:用戶路由重定向到用戶列表路由,若用戶列表沒有權限,則應該重定向到用戶組路由)

  4. 當用戶直接輸入沒有權限的 url 時需要跳轉到沒有權限的頁面或其他操作。(路由限制)

下面我們針對以上問題一個一個解決。

什么時候獲取權限,存儲在哪 & 路由限制

我這里是在 router 的 beforeEach 中獲取的,獲取的 permissionList 是存放在 vuex 中。

原因是考慮到要做路由的限制,以及方便后面項目中對權限列表的使用,以下是實現的示例:

首先我們加入權限配置到 router 上:

// 以下只展示部分配置

{

  path:  /user ,

  name:  User ,

  label:  用戶 ,

  meta: {

    permissions: [ U_1 ]

  },

  redirect: { name:  UserList  },

  children: [

    {

      path:  list ,

      name:  UserList ,

      label:  用戶列表 ,

      meta: {

        permissions: [ U_1_1 ]

      }

    },

    {

      path:  group ,

      name:  UserGroup ,

      label:  用戶組 ,

      meta: {

        permissions: [ U_1_2 ]

      },

      redirect: { name:  UserGroupList  },

      children: [

        {

          path:  list ,

          name:  UserGroupList ,

          label:  用戶組列表 ,

          meta: {

            permissions: [ U_1_2_1 ]

          }

        },

        {

          path:  config ,

          name:  UserGroupConfig ,

          label:  用戶組設置 ,

          meta: {

            permissions: [ U_1_2_2 ]

          }

        }

      ]

    }

  ]

}

可以看到我們把權限加在了 meta 上,是為了更簡單的從 router.beforeEch 中進行權限判斷,權限設置為一個數組,是因為一個頁面可能涉及多個權限。

接下來我們設置 router.beforeEach :

// 引入項目的 vuex

import store from  @/store

// 引入判斷是否擁有權限的函數

import { includePermission } from  @/utils/permission

 

router.beforeEach(async (to, from, next) => {

  // 先判斷是否為登錄,登錄了才能獲取到權限,怎么判斷登錄就不寫了

  if (!isLogin) {

    try {

      // 這里獲取 permissionList

      await store.dispatch( getPermissionList )

      // 這里判斷當前頁面是否有權限

      const { permissions } = to.meta

      if (permissions) {

        const hasPermission = includePermission(permissions)

        if (!hasPermission) next({ name:  NoPermission  })

      }

      next()

    }

  } else {

    next({ name:  Login  })

  }

})

我們可以看到我們需要一個判斷權限的方法 & vuex 中的 getPermissionList 如下:

// @/store

    export default {

      state: {

        permissionList: []

      },

      mutations: {

        updatePermissionList: (state, payload) => {

          state.permissionList = payload

        }

      },

      actions: {

        getPermissionList: async ({ state, commit }) => {

          // 這里是為了防止重復獲取

          if (state.permissionList.length) return

          // 發送請求方法省略

          const list = await api.getPermissionList()

          commit( updatePermissionList , list)

        }

      }

    }
// @/utils/permission

import store from  @/store

 

/**

 * 判斷是否擁有權限

 * @param {Array<string>} permissions - 要判斷的權限列表

 */

function includePermission (permissions = []) {

  // 這里要判斷的權限沒有設置的話,就等於不需要權限,直接返回 true

  if (!permissions.length) return true

  const permissionList = store.state.permissionList

  return !!permissions.find(permission => permissionList.includes(permission))

}

重定向問題

 

 

轉載於:https://www.cnblogs.com/duanlibo/p/12033858.html

    https://blog.csdn.net/ningqiugu/article/details/83591112

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM