zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    【VUE3.0体验】关于路由的一些坑
    TensorFlow中的卷积函数
    TensorFlow源码安装
    ubuntu远程桌面
    TensorFlow图像处理API
    C程序员眼里的Python
    深度剖析HashMap的数据存储实现原理(看完必懂篇)
    golang 互斥锁和读写锁
    golang goroutine的调度
    golang channel的使用以及调度原理
  • 原文地址:https://www.cnblogs.com/yizhilin/p/12902356.html
Copyright © 2011-2022 走看看