vue后台管理项目中如何做权限管理

228 阅读2分钟

--全文基于最近练习的人力资源项目 --

一、权限管理模式

1.RBAC

  • role based access control 基于角色的权限控制
  • 说的通俗一点,就是把权限分配给角色,把角色分配给用户

单独直接给员工分配权限

image.png 给角色分配权限,再给员工分配角色

image.png

第一种选择:

  • 相对来说, 给每个员工一个一个添加权限非常耗时, 而且非常麻烦

第二种选择

  • 只需要提供一个中间角色的概念, 就可以将所有的权限对应分配给角色
  • 我们只需要根据员工所具备的权限分配角色就可以了

假如还有一种情况:

  • 将来如果这个人身兼好多职位(又做了财务主管)
  • 那么就不需要再一个个添加财务相关的权限了
  • 只需要分配一个财务主管的角色, 那么对应财务所有的权限都分配给他了

image.png

二.权限管理方式

1. 页面访问权

1. 拆分静态路由-动态路由

//静态路由
export const constantRoutes = [
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },

  {
    path: '/404',
    component: () => import('@/views/404'),
    hidden: true
  },

  {
    path: '/',
    component: Layout,
    redirect: '/dashboard',
    children: [{
      path: 'dashboard',
      name: 'Dashboard',
      component: () => import('@/views/dashboard/index'),
      meta: { title: '首页', icon: 'dashboard' }
    }]
  },
]
// 动态路由
export const asyncRoutes = [
  departmentRouter,
  roleRouter,
  employeeRouter,
  permissionRouter,
  attendanceRouter,
  approvalRouter,
  salaryRouter,
  socialRouter
  ]

2.根据用户权限添加动态路由

如何匹配用户的权限?

用户信息中,根据menus中的权限点去匹配动态路由数组对象中的name属性

image.png

image.png

import router from '@/router'
import nProgress from 'nprogress'
import '@/styles/nprogress.css'
import { asyncRoutes } from '@/router/index'
import store from './store'
nProgress.configure({
  showSpinner: false
})//进度条配置
router.beforeEach(async(to, from, next) => {
  nProgress.start()
  const whiteList = ['/login', '/404']
  const token = store.getters.token
  if (token) {
    if (to.path === '/login') {
      next('/')
      nProgress.done()
    } else {
    //权限控制
      if (!store.getters.userId) {
        const { roles } = await store.dispatch('user/getUserInfo')
        const filterRoutes = asyncRoutes.filter(item => {
          return roles.menus.includes(item.name)
        })//根据权限点筛选出新的路由数组
        store.commit('user/setRoutes', filterRoutes)//vuex中存储新的路由列表
        router.addRoutes([...filterRoutes, { path: '*', redirect: '/404', hidden: true }])   // 添加动态路由信息到路由表
        next(to.path) // router添加动态路由之后 需要转发一下
      }
      next()
    }
  } else {
    if (whiteList.includes(to.path)) {
      next()
    } else {
      next('/login')
      nProgress.done()
    }
  }
})
router.afterEach((to, from, next) => {
  nProgress.done()
})

之后就可以在左侧菜单获取vuex中的路由信息去渲染左侧菜单,记得退出登录重置路由 resetRouter()

2. 按钮使用权

全局封装自定义指令

// 封装自定义指令 用来控制操作权
Vue.directive('permission', {
  // 会在指令作用的元素插入到页面完成以后触发
  inserted(el, binding) {
    // el 指令作用的元素的dom对象
    console.log(el)
    const points = store.state.user.userInfo?.roles?.points || [] // 当前用户信息的操作权
    if (!points.includes(binding.value)) {
      // 不存在就要删除或者禁用
      el.remove() // 删除元素
    }
  }
})

3. 接口api访问权

服务器通过Token对用户权限进行权限控制,看Token是否合法,合法用户就可以正常访问api接口,否则服务器不返回数据