16.Vue 权限管理

1.什么是权限管理

        权限是对特定资源的访问许可,权限控制就是确保用户只能访问到被分配的资源,而前端权限归根结底是请求的发起权,请求的发起可能有下面两种形式触发

        1.页面加载触发(路由)

        2.页面上的按钮点击触发(视图)

        

2.如何实现

        前端权限控制可以分为四个方面

         1.接口权限

         2.按钮权限

         3.菜单权限

         4.路由权限

2.1 接口权限

        接口权限一般采用jwt的形式验证,至于什么是jwt,后续文章会进行讲解,没有通过的话会返回401,跳转到登陆页面

        登陆完拿到token,将token存起来,通过axios请求拦截器进行拦截,每次请求的时候头部必须携带token

        

axios.interceptors.request.use(config => {
  config.headers['token'] = cookie.get('token')
  return config
})
axios.interceptors.response.use(res => { }, { response }=> {
   //若token过期或发生错误
  if(response.data.code === 40099 || response.data.code === 40098) { 
    router.push('/login')
  }
})

2.2 路由权限控制

方案一

初始化即挂载全部路由,并且在路由上标记相应的权限信息,每次路由跳转前做校验,利用router.beforeEach() 这一个路由守卫对路由跳转进行拦截,判断meta中的信息

const routerMap = [
  {
    path: '/permission',
    component: Layout,
    redirect: '/permission/index',
    // 一直可以被访问
    alwaysShow: true,
    meta: {
      title: 'permission',
      icon: 'lock',
      // 设置谁可以访问
      roles: ['admin', 'editor']
    },
    children: [{
      path: 'page',
      component: () => import('@/views/permission/page'),
      name: 'pagePermission',
      meta: {
        title: 'pagePermission',
        roles: ['admin'] 
      }
    }, {
      path: 'directive',
      component: () => import('@/views/permission/directive'),
      name: 'directivePermission',
      meta: {
        title: 'directivePermission'
      }
    }]
  }
]

缺点

1.加载所有的路由,如果路由很多,而用户并不是所有的路由都有权限访问,对性能会有影响

2.全局路由守卫里,每次路由跳转都要做权限判断

3.菜单信息写死在前端,要改个显示文字或权限信息,需要重新编译

4.菜单和路由耦合在一起,定义路由的时候还有添加菜单显示标题,图标之类的信息,而且路由不一定作为菜单显示。

方案二

初始化的时候挂载不需要权限控制,如登录页,404错误页。如果用户通过输入URL进行强制访问,则直接进入404,从源头上做控制

登录后,获取用户的权限信息,然后筛选有权限的路由,在全局路由守卫调用addRoutes添加路由

这里就不做代码演示了,主要是在合适的时机调用this.$route.addRoutes()这个Vue2API

缺点:

        1.全局路由守卫里,每次路由跳转都要做判断

        2.菜单信息写死在前端,要改个显示文字或权限信息,需要重新编译

        3.菜单和路由耦合在一起,定义路由的时候还有添加菜单显示标题,图标之类的信息,而且路由不一定作为菜单显示。

2.3 菜单权限

菜单权限可以理解成页面与路由解耦

方案一

菜单与路由分离,菜单由后端返回

定义路由


{
  name: "login",
  path: "/login",
  component: () => import("@/pages/Login.vue")
}

全局路由守卫判断


function hasPermission (router, accessMenu) {
  if (whiteList.indexOf(router.path) !== -1) {
    return true
  }
  const menu = Util.getMenuByName(router.name, accessMenu)
  if (menu.name) {
    return true
  }
  return false
}

Router.beforeEach(async (to, from, next) => {
  if (getToken()) {
    const userInfo = store.state.user.userInfo
    if (!userInfo.name) {
      try {
        await store.dispatch('GetUserInfo')
        await store.dispatch('updateAccessMenu')
        if (to.path === '/login') {
          next({ name: 'home_index' })
        } else {
          // Util.toDefaultPage([...routers], to.name, router, next);
          next({ ...to, replace: true })// ,
        }
      } catch (e) {
        if (whiteList.indexOf(to.path) !== -1) { //
          next()
        } else {
          next('/login')
        }
      }
    } else {
      if (to.path === '/login') {
        next({ name: 'home_index' })
      } else {
        if (hasPermission(to, store.getters.accessMenu)) {
          Util.toDefaultPage(store.getters.accessMenu, to, routes, next)
        } else {
          next({ path: '/403', replace: true })
        }
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) { //
      next()
    } else {
      next('/login')
    }
  }
  const menu = Util.getMenuByName(to.name, store.getters.accessMenu)
  Util.title(menu.title)
})
Router.afterEach((to) => {
  window.scrollTo(0, 0)
})

缺点

        1.菜单与路由对应,前端添加新功能,需要通过菜单管理功能添加新的菜单,若菜单配置不对则会导致应用不能正常使用

        2.全局路由守卫里,每次路由跳转都要做判断

方案二

菜单和路由都由后端返回

前端统一定义路由组件

 const Home = () => import("../pages/Home.vue");
 const UserInfo = () => import("../pages/UserInfo.vue");
 export default {
     home: Home,
     userInfo: UserInfo
 };

后端路由组件返回格式

[
    {
      name: 'home',
      path: '/',
      component: 'home'
    },
    {
      name: 'home',
      path: '/userinfo',
      component: 'userInfo'
    }
]

缺点

        1.全后端配合要求高

        2.全局路由守卫里,每次路由跳转都要做判断

2.4 按钮权限

方案一

用v-if指令判断

方案二

自定义指令

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值