什么是RBAC
- RBAC,是后台管理中常用的权限管理系统,通过把权限分配给角色,再把角色分配给员工来实现权限分配,相较于之前直接给员工赋予权限的做法,RBAC就显得更加简便,而RBAC的实现便是基于花裤衩大佬提供的后台管理系统进行改写。
RBAC的实现思路
- 由于RBAC权限管理是通过已有模板进行的改造,所以在改造之前要先搞明白模板中的侧边导航渲染和路由之间的联系:
<!-- 遍历路由数组 -->
<sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" />
模板中的侧边栏导航是根据路由数组来进行渲染的,所以权限管理中的最基础的页面访问权就要从动态控制路由数组来入手。 * 首先,由于模板中的路由数组是固定的,所以要把固定的路由数组拆封成两个部分:任何人都能访问的基础路由数组
/**
* 静态路由(所有人都可以访问的页面路由)
*/
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,
approvalRouter,
attendanceRouter,
salaryRouter,
socialRouter
]
这样便可以根据用户登陆时获取到的权限点来进行页面访问权的控制了。
- 如果要获取用户权限点,就需要在用户登录之后,页面加载之前就获取,所以唯一理想获取的位置就在路由前置守卫里了,因为在路由守卫放行之前,用户是无法进入页面的,这里获取权限点再根据权限点进行页面访问权的渲染再合适不过了。而通过路由前置守卫获取的获取和设置的动态路由数组并不是可以动态渲染的,所以就需要进行动态渲染的VUEX来辅助动态路由的控制。
// 路由前置守卫中的处理
if (!store.getters.userId) {
const { roles } = await store.dispatch('user/getUserInfo')
const filterRoutes = asyncRoutes.filter(item => {
return roles.menus.includes(item.name)
})
// vuex中state的处理
const state = () => {
return {
route: constantRoutes
}
}
// vuex中的mutations中的处理
setRoutes(state, newRoutes) {
state.route = [...constantRoutes, ...newRoutes]
}
- 获取到的动态路由不仅要存入VUEX,也要通过addRoutes方法动态添加路由,由于本人这次开发使用的是Vue2并非Vue3,所以在Vue2中的addRoutes存在已知bug -- 刷新页面时会会直接进入404页面,所以为了避免此情况需要通过路由首位的方法重新进入一次页面便可解决,如果开发使用的是Vue3而非Vue2的话,直接使用没有bug的addRoute方法即可,最后最重要的一点:404页面的路由必须配置在所有路由的最后面,所以在动态添加路由的时候别忘了在最后添加404页面的路由哦~,最后只需要在渲染侧边导航时用VUEX中的动态路由即可
/**
问题1:addRoutes方法存在已知缺陷,官方给出的解决方案是:再次进入页面 next(to.path)
问题2: { path: '*', redirect: '/404', hidden: true } 404页面必须在路由规则数组的最后面
*/
router.addRoutes([...filterRoutes, { path: '*', redirect:'/404', hidden: true }])
next(to.path)
- 解决了页面访问权的动态控制之后就是页面中的按钮操作权了,相较于页面访问权,按钮操作权的控制就尤为简单了,只需要在获取员工权限点是获取员工的按钮控制点权限,如果根据员工是否有对应按钮的权限点来控制按钮是否可以点击或者显示/隐藏即可。