权限控制(RBAC)

一:RBAC权限控制的概念

        RBAC:基于角色的权限控制,用户+角色+权限,给角色分配权限,给用户分配角色

        分为两部分:1.权限数据管理:管理后台数据,就是用户和角色对应的权限数据

                              2.权限控制:分菜单权限控制和按钮权限控制,在前台控制用户的路由和界面                                      显示(主要是这部分,上面的就是搭页面增删改查)

        权限控制只能在前端做吗?都可以,主要看用户的动态路由在哪生成

二:菜单权限

        1. 这里是要控制用户界面能看到菜单的哪些部分,这些部分是由路由控制的。

        2. 用户信息中包含一个routes属性,这个值是个数组,数组里是当前用户被允许的路由名称                这个数据是什么都行,path或者meta中的属性都可以,只要能代表这个路由就行

        3.首先要把路由进行拆分为3部分

                ①静态 (常量) 路由:所有用户都可以访问的路由,不做筛选

                ②动态 (异步) 路由:代表所有需要进行权限筛选的路由

                ③任意路由:一般指的是兜底的404

        4.所以现在的目的就是:拿到动态路由在用户信息的路由权限数组中筛选,留下有权限的,               把最后筛选完成的路由对象动态添加到路由中

        5.那么在哪完成?获取到用户信息的时候就开始。这里就是store/modules/user.js

        6.首先我们在仓库中定义一个routes : [  ] ,用来供菜单组件根据路由生成对应菜单,同时定               义存入数据的一个commit方法

        7.我们要在获取用户信息的action方法中拿到用户信息中的权限点并进行筛选,为了防止代码              过多影响维护,我们选择在外部定义一个函数来完成筛选的操作

function filterAsyncRoutes(allAsyncRoutes, routeNames) {
  const res= allAsyncRoutes.filter((item) => {
    if (routeNames.inclues(item.name)) {
      if (item.children && item.children.length !== 0) {
        item.children = filterAsyncRoutes(item.children, routeNames);
      }
      return true;
    }
  });
  return res;
}

然后在获取用户信息的action中调用函数+动态添加路由+组织菜单生成需要的路由列表

 async getUserInfo({ commit }) {
    try {
      const result = await reqUserInfo();
      if (result.code === 200 || result.code === 20000) {
        commit("SET_USERINFO", result.data);

        // 拿到用户信息的routes,从所有的动态路由过滤自己的
        let userAsyncRoutes = filterAsyncRoutesForUser(
          cloneDeep(allAsyncRoutes),
          result.data.routes
        );
        // 动态添加路由到路由器,后期点击可以跳转
        router.addRoutes([...userAsyncRoutes, anyRoute]);
        // 构造遍历产生菜单的路由
        commit(
          "SET_MENUROUTES",
          constantRoutes.concat(userAsyncRoutes, anyRoute)
        );
        return "ok";
      } else {
        return Promise.reject("获取用户信息失败");
      }
    } catch (error) {
      return Promise.reject("请求获取用户信息失败");
    }
  },

注意1.上面这段代码中给函数传参的时候用了lodash的cloneDeep方法,因为如果不这样做的话,函数在对子路由进行校验的时候会直接修改源数据,这样allAsyncRoutes异步路由就直接被修改了,切换用户的时候菜单显示会出现问题

2.记得要用router.addRoutes()方法把这两个路由对象动态添加进路由中,因为我们在创建路由的时候只放了常量路由进去

        8.现在用户权限范围里的路由表单已经有了,可以去菜单生成组件中循环生成菜单了

        9.还有个问题,需要在路由守卫中,获取用户信息后next()中加to,next(to),否则会有白屏,出现在高权限账号退出后低权限登录

三:按钮权限

        1.筛选的思路和菜单的思路差不多,但按钮权限要在每个按钮上做判断

        2.那问题就变成了,怎么在按钮上判断,在vue2中有两个方向

                ①写一个自定义指令,在这个自定义指令中判断并决定这个按钮的存在与否

                ②写一个判断函数放在Vue原型上,结合v-if决定 这个按钮加载情况

方法①

// 写一个自定义指令
Vue.directive("has",{
  // 这里是个配置对象,官网有不同属性钩子的含义
  inserted(el,bindings){
    // el是当前使用这个指令的真实dom,bindings.value是指令后面绑定的数据
    if(!store.getters.buttons.includes(bindings.value)){
      // 如果没有这个按钮的名字 删除这个按钮
      el.parentNode.removeChild(el)
    }
  }
})

<button v-has="xxx">

方法②:

export function hasBtn(str) {
  return store.getters.buttons?.includes(str);
}

/main.js

import {hasBtn} from "/xxx"

new Vue({

 beforeCreate(){
    Vue.prototype.$has=hasBtn
 }

})

<button v-if=" $has("xxx") " />

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值