vue router 路由鉴权(非动态路由)

栏目: 编程语言 · 发布时间: 4年前

内容简介:实际系统中还有几种管理员,此处略去,以精简描述。原本想用动态路由的思路去做,按权限加载对应路由表,但是由于权限可以交叉(比如一个人可以同时是主题管理员和数据服务管理员),导致权限路由表还是得去做判断组合。于是放弃了这个思路,索性就在beforeEach里直接判断了。用户登陆信息请求后端接口,返回菜单、权限、版权信息等公共信息,存入vuex。此处用到权限字段如下:

概述

  • 角色:超级管理员、主题管理员、数据服务管理员
  • 权限:
    超级管理员:所有页面
    主题管理员:基础公共页面+ 主题设置页
    数据服务管理员:基础公共页面+ 数据服务设置页 + 数据服务审批页
  • 需求:角色菜单来自后端,当用户未通过页面菜单,直接从地址栏访问非权限范围内的url时,拦截用户访问并重定向到首页。

实际系统中还有几种管理员,此处略去,以精简描述。

原本想用动态路由的思路去做,按权限加载对应路由表,但是由于权限可以交叉(比如一个人可以同时是主题管理员和数据服务管理员),导致权限路由表还是得去做判断组合。于是放弃了这个思路,索性就在beforeEach里直接判断了。

实现

路由概览

// index.js
import Vue from 'vue'
import Router from 'vue-router'

import LabelMarket from './modules/label-market'
import PersonalCenter from './modules/personal-center'
import SystemSetting from './modules/system-setting'

import API from '@/utils/api'

Vue.use(Router)

const routes = [
  {
    path: '/label',
    component: () => import(/* webpackChunkName: "index" */ '@/views/index.vue'),
    redirect: { name: 'LabelMarket' },
    children: [
      { // 基础公共页面
        path: 'label-market',
        name: 'LabelMarket',
        component: () => import(/* webpackChunkName: "label-market" */ '@/components/page-layout/OneColLayout.vue'),
        redirect: { name: 'LabelMarketIndex' },
        children: LabelMarket
      },
      { // 个人中心
        path: 'personal-center',
        name: 'PersonalCenter',
        redirect: '/label/personal-center/my-apply',
        component: () => import(/* webpackChunkName: "personal-center" */ '@/components/page-layout/TwoColLayout.vue'),
        children: PersonalCenter
      },
      { // 系统设置
        path: 'system-setting',
        name: 'SystemSetting',
        redirect: '/label/system-setting/theme',
        component: () => import(/* webpackChunkName: "system-setting" */ '@/components/page-layout/TwoColLayout.vue'),
        children: SystemSetting
      }]
  },
  {
    path: '*',
    redirect: '/label'
  }
]

const router = new Router({ mode: 'history', routes })
// personal-center.js
export default [
    ...
  { // 我的审批
    path: 'my-approve',
    name: 'PersonalCenterMyApprove',
    component: () => import(/* webpackChunkName: "personal-center" */ '@/views/personal-center/index.vue'),
    children: [
      { // 数据服务审批
        path: 'api',
        name: 'PersonalCenterMyApproveApi',
        meta: {
          requireAuth: true,
          authRole: 'dataServiceAdmin'
        },
        component: () => import(/* webpackChunkName: "personal-center" */ '@/views/personal-center/api-approve/index.vue')
      },
      ...
    ]
  }
]
export default [
    ...
  { // 数据服务设置
    path: 'api',
    name: 'SystemSettingApi',
    meta: {
      requireAuth: true,
      authRole: 'dataServiceAdmin'
    },
    component: () => import(/* webpackChunkName: "system-setting" */ '@/views/system-setting/api/index.vue')
  },
  { // 主题设置
    path: 'theme',
    name: 'SystemSettingTheme',
    meta: {
      requireAuth: true,
      authRole: 'topicAdmin'
    },
    component: () => import(/* webpackChunkName: "system-setting" */ '@/views/system-setting/theme/index.vue')
  },
    ...
]

鉴权判断

用户登陆信息请求后端接口,返回菜单、权限、版权信息等公共信息,存入vuex。此处用到权限字段如下:

_userInfo: {
    admin:false, // 是否超级管理员
    dataServiceAdmin:true, // 是否数据服务管理员
    topicAdmin:false // 是否主题管理员
}

权限判断逻辑如下:

  1. 判断当前路由是否需要鉴权(router中meta字段下requireAuth是否为true),让公共页面直接放行;
  2. 判断角色是超级管理员,直接放行;
  3. (本系统特殊逻辑)判断跳转路径是主题设置但角色不为主题管理员,继续判断角色是否为数据服务管理员,跳转数据服务设置页or重定向(‘系统设置’菜单'/label/system-setting'默认重定向到'/label/system-setting/theme',其他菜单默认重定向的都是基础公共页面,故需要对这里的重定向鉴权。系统设置的权限不是主题管理员就一定是数据服务管理员,所以能这样做);
  4. 判断路由需求权限是否符合,若不符合直接重定向。
// index.js
router.beforeEach(async (to, from, next) => {
  try {
    // get user login info
    const _userInfo = await API.get('/common/query/menu', {}, false)
    router.app.$store.dispatch('setLoginUser', _userInfo)

    if (_userInfo && Object.keys(_userInfo).length > 0 &&
      to.matched.some(record => record.meta.requireAuth)) {
      if (_userInfo.admin) { // super admin can pass
        next()
      } else if (to.fullPath === '/label/system-setting/theme' &&
        !_userInfo.topicAdmin) {
        if (_userInfo.dataServiceAdmin) {
          next({ path: '/label/system-setting/api' })
        } else {
          next({ path: '/label' })
        }
      } else if (!(_userInfo[to.meta.authRole])) {
        next({ path: '/label' })
      }
    }
  } catch (e) {
    router.app.$message.error('获取用户登陆信息失败!')
  }
  next()
})

以上所述就是小编给大家介绍的《vue router 路由鉴权(非动态路由)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

REST实战

REST实战

Jim Webber、Savas Parastatidis、Ian Robinson / 李锟、俞黎敏、马钧、崔毅 / 东南大学出版社 / 2011-10 / 78.00元

为何典型的企业项目无法像你为web所开发的项目那样运行得如此平滑?对于建造分布式和企业级的应用来说,rest架构风格真的提供了一个可行的替代选择吗? 在这本富有洞察力的书中,三位soa专家对于rest进行了讲求实际的解释,并且通过将web的指导原理应用到普通的企业计算问题中,向你展示了如何开发简单的、优雅的分布式超媒体系统。你将会学习到很多技术,并且随着一家典型的公司从最初的小企业逐渐成长为......一起来看看 《REST实战》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

MD5 加密
MD5 加密

MD5 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具