后台系统中RBAC权限设计详解

1,365 阅读5分钟

在一些大型公司中,很多都有人资的中、后台系统,但在这个系统里面,不是每个人进入都可以对里面的数据进行操作。正常情况下只有少部分的人可以完成例如:人事调整,部门调整,职位调整,薪资调整等一系列的操作。 为了达成不同的帐号登陆系统后能看到不同的页面,能执行不同的功能的目标,我们有很多种解决方案,RBAC(Role-Based Access control)权限模型 ,也就是基于角色的权限分配解决方案。

一、RBAC权限模型的组成

1. 用户(使用系统的员工账号)

一个系统首先会有用户.后台系统的用户基本都是公司的员工

2. 角色(也可以理解成职务)

角色是一个虚拟的人物,正常情况下,我们不可能对每一个用户一 一进行添加权限的操作 就算公司人员比较少,我们添加了了,后期进行人事调动的时候,重新进行权限的分配也是很麻烦的操作

3. 权限点(这个系统中有多少个功能)

每一个功能可以代表一个权限点,也可以理解成一个页面 例始:有3个页面,每个页面上各自有3,2,4个不同的操作 上面的3个页面可以理解成三个大的权限页面,权限页面里面有不同的权限操作

4.权限模型

请添加图片描述 通过对不用的用户分配拥有不同权限点的操作,实现权限的管理 注意点: 1.系统中的权限点不可以随意,必须是程序员已经开发出来的功能!! 2.角色的权限点是可以进行改变的,根据实际情况可以由系统管理员进行权限点的添加和删除 3.用户和角色是1对多的关系:一个用户可以拥有多个角色,这样他就会具体这多个角色的权限了。比如公司的董事长可以拥有财务主管和保安队长的角色: 董事长可以看财务报表,也可以查看监控。

二、RBAC权限动态生成左侧菜单-整体分析

1. 动态添加路由配置

用户能访问到的页面(路由配置)必须是动态的, 所以要先掌握一个可以动态添加路由地址的API addRoutes()方法:动态添加路由配置

router.addRoutes([路由配置对象])
或者:
this.$router.addRoutes([路由配置对象])
2. 登录成功(页面跳转),进入导航守卫:

请添加图片描述 通过事先的约定值,给需要权限的页面进行name的绑定,再通过这个值进行路由的筛选和动态添加,方便后面进入主页的动态菜单生成

在路由导航文件中可以这么进行书写

// 引入所有的动态路由表(未经过筛选)
 import router, { asyncRoutes } from '@/router'

const whiteList = ['/login', '/404']
router.beforeEach(async(to, from, next) => {
....
  if (token) {
    // 有token
    if (to.path === '/login') {
      next('/')
    } else {
      if (!store.getters.userId) {
        await store.dispatch('user/getUserInfo')
        // 改写成动态添加的方式
       router.addRoutes(asyncRoutes)
      }
      next()
    }
  } else {
    // 没有token
    if (whiteList.includes(to.path)) {
      next()
    } else {
      next('/login')
    }
  }
})

在路由跳转到主页前,将动态的路由添加,然后等待渲染,这样就可以完成不同角色的员工进入主页的不同菜单 请添加图片描述 这个过程我们可以使用vuex进行管理,在vuex中进行动态路由与静态路由的结合

// 导入静态路由
import { constantRoutes } from '@/router'
export default {
  namespaced: true,
  state: {
    // 先以静态路由作为菜单数据的初始值
    menuList: [...constantRoutes]
  },
  mutations: {
    setMenuList(state, asyncRoutes) {
      // 将动态路由和静态路由组合起来
      state.menuList = [...constantRoutes, ...asyncRoutes]
    }
  }
}

三、刷新页面时的bug修复

(1).解决刷新页面后直接进入404的问题

1. 问题

(1)如果我们刷新浏览器,会发现跳到了404页面

(2)对于addRoute添加的路由,在刷新时会白屏

2. 原因

刷新浏览器,会发现跳到了404页面

现在我们的路由设置中的404页处在中间位置而不是所有路由的末尾了。

3.解决

把404页改到路由配置的最末尾就可以了,将其push进去

(2).解决刷新出现的白屏bug

在路由next()前加添加这么一段代码就可以了

if (!store.getters.userId) {
  // 省略其他...
  // 解决刷新出现的白屏bug
  next({
    ...to, // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次)
    replace: true // 重进一次, 不保留重复历史
  })
} else {
  next()
}

(3).退出登录时重置路由

1.问题

退出后,再次登陆,发现菜单异常 (控制台有输出说路由重复); 请添加图片描述

2.原因

路由设置是通过router.addRoutes(filterRoutes)来添加的,退出时,并没有清空,再次登陆,又加了一次,所以有重复。

需要将路由权限重置 (恢复默认) 将来登录后再次追加才可以,不然的话,就会重复添加

3.解决

// 重置路由
export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // 重新设置路由的可匹配路径
}

这个方法就是将路由重新实例化,相当于换了一个新的路由,之前加的路由就不存在了,需要在登出的时候, 调用一下即可。