RBAC权限设计思想
公司里有不同的职能部门,都在用同一套系统 ,不一样部门的人员进入系统里面需要操作的事情是不一样的
必定需要根据不同的员工角色配置不同的权限
一种基于角色的设计思想
- 给员工配置角色 (一个员工可以拥有多个角色)
- 给角色配置权限 (一个角色可以有多个权限)
权限控制
我们实现了RBAC权限设计思想的各个环节后,接下来我们就可以利用这些权限点做实际的权限控制,在当前项目里,权限的控制有两个地方:
- 菜单权限控制(不同的用户进来系统之后,看到的菜单是不同的)
- 操作按钮权限控制 (页面上的按钮,不同的人也有不同权限)
1、页面级权限控制
流程图:
用户能访问哪些页面是通过actions获取到的,需要从action中返回。
actions: {
// 发送请求
... ...
// 当前用户可以看到的菜单 res.data.roles.menus
return res
},
在路由守卫里面:
获取到权限信息,然后再在所有路由列表里过滤掉非当前用户权限
// 获取权限信息
const res = await store.dispatch('user/getUserProfile')
// console.log(res.data.roles.menus)
// 接收到当前用户权限信息
const menus = res.data.roles.menus
// 在所有路由列表里过滤掉非当前用户权限
const filterRoles = asyncRoutes.filter(item => {
const name = item.children[0].name
return menus.includes(name)
})
在根据权限信息动态添加路由,并将权限列表储存到vuex中
// 根据权限信息动态添加路由
router.addRoutes(filterRoles)
// 将权限列表储存到vuex中
store.commit('menu/updateMenuList', filterRoles)
在以上代码下面加上如下代码:
store.commit('menu/updateMenuList', filterRoles)
// 解决刷新出现的白屏bug
next({
...to, // next({ ...to })的目的,是保证路由添加完了再进入页面
replace: true // 重进一次, 不保留重复历史
})
最后,在登出时,要重置路由,不然再次登录时会报错。
// 在登出时调用该方法
// 重置路由
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // 重新设置路由的可匹配路径
}
2、按钮级权限控制
流程图:
在vuex中获取到按钮权限列表
// 从vuex中取出points,
const points = store.state.user.userInfo.roles.points
在main.js中注册一个自定义指令
// 导入
import store from '@/store'
// 注册一个全局自定义指令
export default {
install(Vue) {
Vue.directive('allow', {
inserted: function(el, binding) {
const points = store.state.user.userInfo.roles
// 如果points没有binding.value则删除该按钮
if (!points.includes(binding.value)) {
el.parentNode.removeChild(el)
}
// 如果points有binding.value则显示
}
})
}
}
在页面的按钮上加上
// 自定义指令
v-allow="'import_excel'"
至此,两种权限控制都已经完成。