Vue 权限控制的两种方法(路由验证)


Posted in Javascript onAugust 16, 2019

下面介绍两种权限控制的方法:

  • 路由元信息(meta)
  • 动态加载菜单和路由(addRoutes)

路由元信息(meta)

如果一个网站有不同的角色,比如 管理员 和 普通用户 ,要求不同的角色能访问的页面是不一样的

这个时候我们就可以 把所有的页面都放在路由表里 ,只要 在访问的时候判断一下角色权限 。如果有权限就让访问,没有权限的话就拒绝访问,跳转到404页面

vue-router 在构建路由时提供了元信息 meta 配置接口,我们可以在元信息中添加路由对应的权限,然后在路由守卫中检查相关权限,控制其路由跳转。

可以在每一个路由的 meta 属性里,将能访问该路由的角色添加到 roles 里。用户每次登陆后,将用户的角色返回。然后在访问页面时,把路由的 meta 属性和用户的角色进行对比,如果用户的角色在路由的 roles 里,那就是能访问,如果不在就拒绝访问。

代码示例1:

路由信息:

routes: [
  {
    path: '/login',
    name: 'login',
    meta: {
      roles: ['admin', 'user']
    },
    component: () => import('../components/Login.vue')
  },
  {
    path: 'home',
    name: 'home',
    meta: {
      roles: ['admin']
    },
    component: () => import('../views/Home.vue')
  },
]

页面控制:

//假设有两种角色:admin 和 user 
//从后台获取的用户角色
const role = 'user'
//当进入一个页面是会触发导航守卫 router.beforeEach 事件
router.beforeEach((to,from,next)=>{
 if(to.meta.roles.includes(role)){
 next() //放行
 }esle{
 next({path:"/404"}) //跳到404页面
 }
})

代码示例2

当然也可以用下面的一种方法:

// router.js
// 路由表元信息
[
 {
  path: '',
  redirect: '/home'
 },
 {
  path: '/home',
  meta: {
   title: 'Home',
   icon: 'home'
  }
 },
 {
  path: '/userCenter',
  meta: {
   title: '个人中心',
   requireAuth: true // 在需要登录的路由的meta中添加响应的权限标识
  }
 }
]

// 在守卫中访问元信息
function gaurd (to, from, next) {
 // to.matched.some(record => record.meta.requireAuth)
 // 可在此处
}

可以在多个路由下面添加这个权限标识,达到控制的目的

只要一切换页面,就需要看有没有这个权限,所以可以在最大的路由下 main.js 中配置

存储信息

一般的,用户登录后会在本地存储用户的认证信息,可以用 token 、 cookie 等,这里我们用 token 。

将用户的 token 保存到 localStorage 里,而用户信息则存在内存 store 中。这样可以在 vuex 中存储一个标记用户登录状态的属性 auth ,方便权限控制。

代码示例

// store.js
{
 state: {
  token: window.localStorage.getItem('token'),
  auth: false,
  userInfo: {}
 },
 mutations: {
  setToken (state, token) {
   state.token = token
   window.localStorage.setItem('token', token)
  },
  clearToken (state) {
   state.token = ''
   window.localStorage.setItem('token', '')
  },
  setUserInfo (state, userInfo) {
   state.userInfo = userInfo
   state.auth = true // 获取到用户信息的同时将auth标记为true,当然也可以直接判断userInfo
  }
 },
 actions: {
  async getUserInfo (ctx, token) {
   return fetchUserInfo(token).then(response => {
    if (response.code === 200) {
     ctx.commit('setUserInfo', response.data)
    }
    return response
   })
  },
  async login (ctx, account) {
   return login(account).then(response => {
    if (response.code === 200) {
     ctx.commit('setUserInfo', response.data.userInfo)
     ctx.commit('setToken', response.data.token)
    }
   })
  }
 }
}

写好路由表和vuex之后,给所有路由设置一个全局守卫,在进入路由之前进行权限检查,并导航到对应的路由。

// store.js
{
 state: {
  token: window.localStorage.getItem('token'),
  auth: false,
  userInfo: {}
 },
 mutations: {
  setToken (state, token) {
   state.token = token
   window.localStorage.setItem('token', token)
  },
  clearToken (state) {
   state.token = ''
   window.localStorage.setItem('token', '')
  },
  setUserInfo (state, userInfo) {
   state.userInfo = userInfo
   state.auth = true // 获取到用户信息的同时将auth标记为true,当然也可以直接判断userInfo
  }
 },
 actions: {
  async getUserInfo (ctx, token) {
   return fetchUserInfo(token).then(response => {
    if (response.code === 200) {
     ctx.commit('setUserInfo', response.data)
    }
    return response
   })
  },
  async login (ctx, account) {
   return login(account).then(response => {
    if (response.code === 200) {
     ctx.commit('setUserInfo', response.data.userInfo)
     ctx.commit('setToken', response.data.token)
    }
   })
  }
 }
}

上述的方法是基于 jwt 认证方式,本地不持久化用户信息,只保存 token ,当用户刷新或者重新打开网页时,进入需要登录的页面都会尝试去请求用户信息,该操作在整个访问过程中只进行一次,直到刷新或者重新打开,对于应用后期的开发维护和扩展支持都很好。

动态加载菜单和路由(addRoutes)

有时候为了安全,我们需要根据用户权限或者是用户属性去动态的添加菜单和路由表,可以实现对用户的功能进行定制。 vue-router 提供了 addRoutes() 方法,可以动态注册路由, 需要注意的是,动态添加路由是在路由表中 push 路由,由于路由是按顺序匹配的,因此需要将诸如404页面这样的路由放在动态添加的最后。

代码示例

// store.js
// 将需要动态注册的路由提取到vuex中
const dynamicRoutes = [
 {
  path: '/manage',
  name: 'Manage',
  meta: {
   requireAuth: true
  },
  component: () => import('./views/Manage')
 },
 {
  path: '/userCenter',
  name: 'UserCenter',
  meta: {
   requireAuth: true
  },
  component: () => import('./views/UserCenter')
 }
]

在 vuex 中添加 userRoutes 数组用于存储用户的定制菜单。在setUserInfo中根据后端返回的菜单生成用户的路由表。

// store.js
setUserInfo (state, userInfo) {
 state.userInfo = userInfo
 state.auth = true // 获取到用户信息的同时将auth标记为true,当然也可以直接判断userInfo
 // 生成用户路由表
 state.userRoutes = dynamicRoutes.filter(route => {
  return userInfo.menus.some(menu => menu.name === route.name)
 })
 router.addRoutes(state.userRoutes) // 注册路由
}

修改菜单渲染

// App.vue
<div id="nav">
 <router-link to="/">主页</router-link>
 <router-link to="/login">登录</router-link>
 <template v-for="(menu, index) of $store.state.userInfo.menus">
  <router-link :to="{ name: menu.name }" :key="index">{{menu.title}}</router-link>
 </template>
</div>

总结

以上所述是小编给大家介绍的Vue 权限控制的两种方法(路由验证),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
jQuery 使用手册(三)
Sep 23 Javascript
javascript OFFICE控件测试代码
Dec 08 Javascript
HTML页面滚动时获取离页面顶部的距离2种实现方法
Sep 05 Javascript
JS读取XML文件数据并以table形式显示数据的方法(兼容IE与火狐)
Jun 02 Javascript
浅谈javascript的url参数parse和build函数
Mar 04 Javascript
vue子组件使用自定义事件向父组件传递数据
May 27 Javascript
解决AjaxFileupload 上传时会出现连接重置的问题
Jul 07 Javascript
浅谈针对Vue相同路由不同参数的刷新问题
Sep 29 Javascript
JavaScript 中 JSON.parse 函数 和 JSON.stringify 函数
Dec 05 Javascript
ant-design-vue 时间选择器赋值默认时间的操作
Oct 27 Javascript
Vue实现简单购物车功能
Dec 13 Vue.js
vue组件vue-esign实现电子签名
Apr 21 Vue.js
JS中的算法与数据结构之列表(List)实例详解
Aug 16 #Javascript
jQuery zTree插件快速实现目录树
Aug 16 #jQuery
JS中的算法与数据结构之二叉查找树(Binary Sort Tree)实例详解
Aug 16 #Javascript
微信小程序webview组件交互,内联h5页面并网页实现微信支付实现解析
Aug 16 #Javascript
JS中的算法与数据结构之常见排序(Sort)算法详解
Aug 16 #Javascript
jQuery zTree插件使用简单教程
Aug 16 #jQuery
微信小程序 如何保持登录状态
Aug 16 #Javascript
You might like
对象失去焦点时自己动提交数据的实现代码
2012/11/06 PHP
PHP实现数据库的增删查改功能及完整代码
2018/04/18 PHP
PHP实现笛卡尔积算法的实例讲解
2019/12/22 PHP
为jquery.ui.dialog 增加“自动记住关闭时的位置”的功能
2009/11/24 Javascript
jquery ready(fn)事件使用介绍
2013/08/21 Javascript
详解AngularJS中的表格使用
2015/06/16 Javascript
javascript设计模式之对象工厂函数与构造函数详解
2015/07/30 Javascript
jQuery鼠标事件汇总
2015/08/30 Javascript
基于RequireJS和JQuery的模块化编程日常问题解析
2016/04/14 Javascript
jQuery基础知识点总结(DOM操作)
2016/06/01 Javascript
js动态添加的DIV中的onclick事件简单实例
2016/07/25 Javascript
AngularJs  Understanding Angular Templates
2016/09/02 Javascript
vue展示dicom文件医疗系统的实现代码
2018/08/27 Javascript
Vue实现用户自定义字段显示数据的方法
2018/08/28 Javascript
基于Element封装一个表格组件tableList的使用方法
2020/06/29 Javascript
jquery插件懒加载的示例
2020/10/24 jQuery
[05:31]干嘛呢兄弟!DOTA2 TI9语音轮盘部分出处
2019/05/14 DOTA
Windows系统下使用flup搭建Nginx和Python环境的方法
2015/12/25 Python
Python的Scrapy爬虫框架简单学习笔记
2016/01/20 Python
Windows下Eclipse+PyDev配置Python+PyQt4开发环境
2016/05/17 Python
利用ctypes提高Python的执行速度
2016/09/09 Python
centos6.8安装python3.7无法import _ssl的解决方法
2018/09/17 Python
使用Python做定时任务及时了解互联网动态
2019/05/15 Python
python+OpenCV实现车牌号码识别
2019/11/08 Python
PyCharm使用Docker镜像搭建Python开发环境
2019/12/26 Python
Python之变量类型和if判断方式
2020/05/05 Python
使用canvas来完成线性渐变和径向渐变的功能的方法示例
2019/07/25 HTML / CSS
名词解释WEB SERVICE,SOAP,UDDI,WSDL,JAXP,JAXM;JSWDL开发包的介绍。
2012/10/27 面试题
经理秘书岗位职责
2013/11/14 职场文书
教师年度考核自我鉴定
2014/01/19 职场文书
求职信模板标准格式范文
2014/02/23 职场文书
体育课课后反思
2014/04/24 职场文书
软件售后服务方案
2014/05/29 职场文书
交通志愿者活动总结
2014/06/27 职场文书
优秀教师先进材料
2014/12/16 职场文书
六年级作文之自救
2019/12/19 职场文书