前言

现在流行的前端框架很多,有若依、eladmin等框架,这些框架都是用于做后台管理的框架,既然是后台管理那么就会涉及到一个比较关键性的问题就是权限管理

什么是权限管理

既然是后台管理登录的人的角色可能是超级管理员、管理员、以及普通用户或者有更多的层级角色,这些不同的角色登入后台管理系统左侧导航栏的显示是不同的,实现不同角色登录后台管理系统左侧的导航栏显示不同就是实现权限管理。
在这里插入图片描述

很多文章都写的是后端如何实现后台管理系统,以若依框架为例来说说前端是如何实现权限管理的。

思路

  1. 将用户的权限字符存入数据库,当用户登录后根据用户的登录信息获取用户的所有信息(包括用户的权限信息)存入Vuex中。

    // 获取用户信息
    GetInfo({ commit, state }) {
      return new Promise((resolve, reject) => {
        getInfo().then(res => {
          const user = res.user
          const avatar = (user.avatar == "" || user.avatar == null) ? require("@/assets/images/profile.jpg") : user.avatar;
          if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
            commit('SET_ROLES', res.roles)
            commit('SET_PERMISSIONS', res.permissions)
          } else {
            commit('SET_ROLES', ['ROLE_DEFAULT'])
          }
          commit('SET_NAME', user.userName)
          commit('SET_USER', user)
          commit('SET_AVATAR', avatar)
          resolve(res)
        }).catch(error => {
          reject(error)
        })
      })
    },
    
  2. 将路由分为公共路由动态路由(基于用户权限动态去加载)

    公共路由

    export const constantRoutes = [
      {
        path: '/redirect',
        component: Layout,
        hidden: true,
        children: [{
          path: '/redirect/:path(.*)',
          component: () =>
            import ('@/views/redirect')
        }]
      },
    ]
    

    动态路由

    export const dynamicRoutes = [
        {
            path: '/',
            component: NavigationBar,
            hidden: true,
            permissions: ['system:user:edit'],
            children: [{
                path: 'system/user-auth',
                component:Layout,
                children: [{
                    path: 'role/:userId(\\d+)',
                    component: () =>
                        import('@/views/system/user/authRole'),
                    name: 'AuthRole',
                    meta: { title: '分配角色', activeMenu: '/system/user' }
                }]
            }]
        },
        
        {
            path: '/',
            component: NavigationBar,
            hidden: true,
            permissions: ['system:role:edit'],
            children:[{
                path:'system/role-auth',
                component:Layout,
                children: [{
                path: 'user/:roleId(\\d+)',
                component: () =>
                    import ('@/views/system/role/authUser'),
                name: 'AuthUser',
                meta: { title: '分配用户', activeMenu: '/system/role' }
            }]
            }]
            
        },
        {
            path: '/system/dict-data',
            component: Layout,
            hidden: true,
            permissions: ['system:dict:list'],
            children: [{
                path: 'index/:dictId(\\d+)',
                component: () =>
                    import ('@/views/system/dict/data'),
                name: 'Data',
                meta: { title: '字典数据', activeMenu: '/system/dict' }
            }]
        },
        {
            path: '/monitor/job-log',
            component: Layout,
            hidden: true,
            permissions: ['monitor:job:list'],
            children: [{
                path: 'index',
                component: () =>
                    import ('@/views/monitor/job/log'),
                name: 'JobLog',
                meta: { title: '调度日志', activeMenu: '/monitor/job' }
            }]
        },
        {
            path: '/tool/gen-edit',
            component: Layout,
            hidden: true,
            permissions: ['tool:gen:edit'],
            children: [{
                path: 'index/:tableId(\\d+)',
                component: () =>
                    import ('@/views/tool/gen/editTable'),
                name: 'GenEdit',
                meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
            }]
        }
    ]
    

    从上面的代码中我们可以看出公共路由没有permissions字段,动态路由中有permissions字段。

  3. 根据用户权限中的permissions字段和Vuex中存储permissions字段判断当前登录的用户拥有哪些权限。

    const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
    router.addRoutes(asyncRoutes);
    
    // 动态路由遍历,验证是否具备权限
    export function filterDynamicRoutes(routes) {
      const res = []
      routes.forEach(route => {
        if (route.permissions) {
          if (auth.hasPermiOr(route.permissions)) {
            res.push(route)
          }
        } else if (route.roles) {
          if (auth.hasRoleOr(route.roles)) {
            res.push(route)
          }
        }
      })
      return res
    }    
    
    // 验证用户是否含有指定权限,只需包含其中一个
    hasPermiOr(permissions) {
      return permissions.some(item => {
        return authPermission(item)
      })
    },
    
    function authPermission(permission) {
      const all_permission = "*:*:*";
      const permissions = store.getters && store.getters.permissions
      if (permission && permission.length > 0) {
        return permissions.some(v => {
          return all_permission === v || v === permission
        })
      } else {
        return false
      }
    }
    
Logo

快速构建 Web 应用程序

更多推荐