需求背景:

当我们在做后台管理系统的时候,都会涉及到系统的菜单树如何动态显示的问题。目前基本上都是RBAC的解决方案,即Role-Based Access Control,权限与角色相关联,给用户通设置适当角色的而得到角色的权限

 

路由权限方案:

1、前端路由根据角色控制页面权限:即为每个页面设置允许进入的角色,通过判断用户角色授权进入与否

优点:实现方式简单

缺点:1、不灵活,当一个页面允许进入的角色类型发生变化,代码要更改;2、需要考虑访问的页面没有权限时需要考虑重定向到哪里的问题

2、动态路由:即通过接口返回用户有权限进入的路由列表,路由动态注入

优点:数据只返回有权限路由,不存在访问到无权限的bug;维护权限数据,前端代码不用频繁改动

缺点:需要菜单管理页面配合维护数据

 

项目需求

  • 首页、登录、404等页面无需权限也能访问
  • 剩余页面根据权限配置显示
  • 一级路由显示在顶部导航栏,二级路由页面属于导航页的显示在左侧导航栏
  • 每次切换路由后重新获取下权限
  • 页面的每个按钮也添加权限配置

 

实现方式:

1、路由权限

将页面路由分成两类,一类:白名单,项目初始化时即完成注册,一类:权限路由,根据角色类型获取路由权限数据,动态添加到路由文件,关键代码如下:

//路由白名单
import { routerArr } from './defaultRouts'
const routes: Array<RouteConfig> = [
    ...routerArr,//白名单路由
    {
        path: '/login',
        name: 'login',
        component: () => import('@/pages/layout/login.vue'),
    },
    {
        path: '/401',
        name: '401',
        component: () => import('@/components/error/401.vue')
    },
    {
        path: '*',
        name: '404',
        component: () => import('@/components/error/404.vue')
    },
]

const router = new VueRouter({
    routes,
    // 对于页面跳转,全部都返回到页面顶部。
    scrollBehavior(to, from, savedPosition) {
        return { x: 0, y: 0 };
    }
});
//动态添加路由
// 避免添加重复路由
if (hasOwn(el)) {
    // router路由实例对象
    router.options.routes.push(el)
    router.addRoute(el)
}

 

2、按钮权限设置

对按钮进行类型划分,赋予code属性。给每个页面需要权限的按钮设置数据权限;前端对每个页面的权限按钮数据收集处理(当前采用,将权限按钮的code收集到btnArr内,存放于页面meta);全局注册权限判断方法。关键代码如下

支付权重路由 权限路由_白名单

 

 

// 判断用户是否有按钮权限
Vue.prototype.$btnPermissions = function (code) {
    const btnArr = this.$route.meta.btnArr || []
    return btnArr.includes(code)
}

 

注意事项:

1、动态添加路由,相同路由重复添加—添加前判断路由实例对象中是否已有改路由,有则不添加

2、路由重定向问题——动态拼装或者数据配置一级页面重定向到哪个二级页面

3、如果没有没有默认的白名单页面,登录后页面跳转的处理

 

总结:

权限管理实现方式多种多样,根据自身需求自行定制合适的方案。其核心思想,即RBAC的解决方案。