继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

【金秋打卡】第25天 权限控制解决方案 RBAC

有梦
关注TA
已关注
手记 82
粉丝 27
获赞 19

课程名称:基于Vue3最新标准,实现后台前端综合解



课程章节: 第一章



课程讲师:Sunday


    课程内容

    

是以 用户-> 角色 -> 权限 的一种关系

http://img2.mukewang.com/63757ba600015ee515040666.jpg

登入时 会获取到这些数据

permission 会拿到 菜单定义时 相对应的一个名称

http://img1.mukewang.com/63757ba70001829908100707.jpg

prints 对应的是 用户按钮的权限 

role 是一个数组 你有多少角色 就返回多少角色

动态路由

http://img4.mukewang.com/63757bb90001d0a108481353.jpg

将进行权限控制的路由分别拆开来写 然后将公共的路由单独放在一个json内

export 输出 

在src 文件夹下 设置了 permission.js     main.js 需要引入


import router from './router'
import store from './store'

// 白名单
const whiteList = ['/login']
/**
 * 路由前置守卫
 */
router.beforeEach(async (to, from, next) => {
  // 存在 token ,进入主页
  // if (store.state.user.token) {
  // 快捷访问
  if (store.getters.token) {
    if (to.path === '/login') {
      next('/')
    } else {
      // 判断用户资料是否获取
      // 若不存在用户信息,则需要获取用户信息
      if (!store.getters.hasUserInfo) {
        // 触发获取用户信息的 action,并获取用户当前权限
        const { permission } = await store.dispatch('user/getUserInfo')
        // 处理用户权限,筛选出需要添加的权限
        const filterRoutes = await store.dispatch(
          'permission/filterRoutes',
          permission.menus
        )
        // 利用 addRoute 循环添加
        filterRoutes.forEach(item => {
          router.addRoute(item)
        })
        console.log(router)
        // 添加完动态路由之后,需要在进行一次主动跳转
        return next(to.path)
      }
      next()
    }
  } else {
    // 没有token的情况下,可以进入白名单
    if (whiteList.indexOf(to.path) > -1) {
      next()
    } else {
      next('/login')
    }
  }
})

router.addRoute(item) 是vue-router 4最新提供的动态路由方法

vuex  permission.js

// 专门处理权限路由的模块
import { publicRoutes, privateRoutes } from '@/router'
export default {
  namespaced: true,
  state: {
    // 路由表:初始拥有静态路由权限
    routes: publicRoutes
  },
  mutations: {
    /**
     * 增加路由
     */
    setRoutes(state, newRoutes) {
      // 永远在静态路由的基础上增加新路由
      state.routes = [...publicRoutes, ...newRoutes]
    }
  },
  actions: {
    /**
     * 根据权限筛选路由
     */
    filterRoutes(context, menus) {
      const routes = []
      // 路由权限匹配
      menus.forEach(key => {
        // 权限名 与 路由的 name 匹配
        routes.push(...privateRoutes.filter(item => item.name === key))
      })
      // 最后添加 不匹配路由进入 404
      routes.push({
        path: '/:catchAll(.*)',
        redirect: '/404'
      })
      context.commit('setRoutes', routes)
      return routes
    }
  }
}

将 公共的路由和私有的路由 进行整合 判断 filterRoutes(vuex方法,接口获取的menus的permission.name)

用接口获取的name  做循环判断 是否和 路由定义的name相同 如果有则添加进去

在用户退出时 也需要 router.removeRoute(menu)


/**
 * 初始化路由表
 */
export function resetRouter() {
  if (
    store.getters.userInfo &&
    store.getters.userInfo.permission &&
    store.getters.userInfo.permission.menus
  ) {
    const menus = store.getters.userInfo.permission.menus
    menus.forEach((menu) => {
      router.removeRoute(menu)
    })
  }

功能受控指令 v-permission="['importUser']"

import store from '@/store'

function checkPermission(el, binding) {
  // 获取绑定的值,此处为权限
  const { value } = binding
  // 获取所有的功能指令
  const points = store.getters.userInfo.permission.points
  // 当传入的指令集为数组时
  if (value && value instanceof Array) {
    // 匹配对应的指令
    const hasPermission = points.some(point => {
      return value.includes(point)
    })
    // 如果无法匹配,则表示当前用户无该指令,那么删除对应的功能按钮
    if (!hasPermission) {
      el.parentNode && el.parentNode.removeChild(el)
    }
  } else {
    // eslint-disabled-next-line
    throw new Error('v-permission value is ["admin","editor"]')
  }
}

export default {
  // 在绑定元素的父组件被挂载后调用
  mounted(el, binding) {
    checkPermission(el, binding)
  },
  // 在包含组件的 VNode 及其子组件的 VNode 更新后调用
  update(el, binding) {
    checkPermission(el, binding)
  }
}

自定义了一个 v-permission 设置了内容  判断按钮是否显示

app 也需要引入 app.directive('permission', permission)

http://img.mukewang.com/63757c460001072109890710.jpg













打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP