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

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

  • 路由元信息(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 权限控制的两种方法(路由验证),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • Vue2.0用户权限控制解决方案

    Vue-Access-Control是一套基于Vue/Vue-Router/axios 实现的前端用户权限控制解决方案,通过对路由.视图.请求三个层面的控制,使开发者可以实现任意颗粒度的用户权限控制. 安装 版本要求 Vue 2.0x Vue-router 3.x 获取 git:git clone https://github.com/tower1229/Vue-Access-Control.git npm:npm i vue-access-control 运行 //开发 npm run dev

  • vue-router路由懒加载和权限控制详解

    vue-router路由懒加载 和权限控制,今天刚好搞了一个基于node token验证的小demo 所以下面介绍下,路由懒加载 1.为什么要使用路由懒加载呢 用vue.js写单页面应用时,会出现打包后的JavaScript包非常大,影响页面加载,我们可以利用路由的懒加载去优化这个问题,当我们用到某个路由后,才去加载对应的组件,这样就会更加高效 2.用法 import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) e

  • vue登录路由验证的实现

    vue的项目的登录状态如果用vuex状态管理,页面一刷新vuex管理的状态就会消失,这样登录路由验证就没有意义了.可以将登录的状态写到web Storage中进行存储管理. 步骤如下: 1.在登录组件里,将登录状态写入web Storage里.(一般写入session Storage,会话关闭,存储数据自动删除) if('登录成功') {sessionStorage.setItem('accessToken' , 写入登录成功返回的登录令牌或者自定义的判断字符串) } 2.在需要登录验证的路由元

  • vue中如何实现后台管理系统的权限控制的方法示例

    一.前言 在广告机项目中,角色的权限管理是卡了挺久的一个难点.首先我们确定的权限控制分为两大部分,其中根据粒的大小分的更细: 接口访问的权限控制 页面的权限控制 菜单中的页面是否能被访问 页面中的按钮(增.删.改)的权限控制是否显示 权限控制是什么 在权限的世界里服务端提供的一切都是资源,资源可以由请求方法+请求地址来描述,权限是对特定资源的访问许可,所谓权限控制,也就是确保用户只能访问到被分配的资源.具体的说,前端对资源的访问通常是由界面上的按钮发起,比如删除某条数据:或由用户进入某一个页面发

  • 基于Vue自定义指令实现按钮级权限控制思路详解

    思路: 登录:当用户填写完账号和密码后向服务端验证是否正确,验证通过之后,服务端会返回一个token,拿到token之后(我会将这个token存贮到sessionStorage中,保证刷新页面后能记住用户登录状态),前端会根据token再去拉取一个 user_info 的接口来获取用户的详细信息(如用户权限,用户名等等信息). 权限验证:通过token获取用户对应的 role,自定义指令,获取路由meta属性里btnPermissions( 注: meta.btnPermissions是存放按钮

  • 详解基于vue-router的动态权限控制实现方案

    使用vue开发带权限管理系统,尤其是采用了vue-router做路由,很多人都遇到的一个问题就是如何动态加载路由path对应的component. 典型的应用场景就是:前端菜单不静态的写在vue程序里,而是要从后台程序和数据库返回的菜单来动态加载到vue应用中. 网上很多问权限的问题,但几乎找不到很好的解决答案,在很长一段时间里,非常打击使用vue技术栈开发的信心.最有质量的一篇文章是:http://www.jb51.net/article/124801.htm 但作者并没有完全解决这个问题,还

  • 基于vue,vue-router, vuex及addRoutes进行权限控制问题

    基于vuex, vue-router,vuex的权限控制教程,完整代码地址见 https://github.com/linrunzheng/vue-permission-control 接下来让我们模拟一个普通用户打开网站的过程,一步一步的走完整个流程. 首先从打开本地的服务localhost:8080开始,我们知道打开后会进入login页面,那么判断的依据是什么. 首先是token. 没有登陆的用户是获取不到token的,而登陆后的角色我们会将token存到local或者seesionStor

  • vue-router beforeEach跳转路由验证用户登录状态

    使用vue判断验证用户登录状态 导航钩子类似于生命周期钩子,包含路由进入前,进入后,更新时,退出前等几个周期,主要用于控制导航的前进后退或跳转等. 其中router.beforeEach就是路由进入前的周期,同时有路由的来源和去向两个参数,可以判断和控制当前路由的走向和重定向. 一般router.beforeEach配合vuex全局状态储存使用,验证用户登录状态.也可以结合sessionStorage 和localStorage使用,原理相同. 用户登录状态验证 路由配置 定义需要判断登录状态的

  • vue中路由验证和相应拦截的使用详解

    在web项目中,经常需要根据是否登录进行路由的验证和相应的拦截. 首先,在vuex里的store.js里边写一个存放登录状态,代码如下 import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { user: false }, mutations: { // 登录 login (state, user) { state.user = user }, // 退

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

    下面介绍两种权限控制的方法: 路由元信息(meta) 动态加载菜单和路由(addRoutes) 路由元信息(meta) 如果一个网站有不同的角色,比如 管理员 和 普通用户 ,要求不同的角色能访问的页面是不一样的 这个时候我们就可以 把所有的页面都放在路由表里 ,只要 在访问的时候判断一下角色权限 .如果有权限就让访问,没有权限的话就拒绝访问,跳转到404页面 vue-router 在构建路由时提供了元信息 meta 配置接口,我们可以在元信息中添加路由对应的权限,然后在路由守卫中检查相关权限,

  • Vue 创建组件的两种方法小结(必看)

    创建组件的两种方法小结 1.全局注册 2.局部注册 var child=Vue.extend({}) var parent=Vue.extend({}) Vue.extend() 全局方法 生成构造器,创建子类 使用基础 Vue 构造器,创建一个"子类". 这样写非常繁琐.于是vue进行了简化 使用Vue.component()直接创建和注册组件: Vue.component(id,options) 全局方法 用来注册全局组件 id 是string类型,即是注册组件的名称 option

  • 去掉vue 中的代码规范检测两种方法(Eslint验证)

    我们在使用vue 脚手架时,为了规范团队的代码格式,会有一个代码规范检测,如果不符合规范就会报错,有时候我们不想按照他的规范去写.这时我们需要关闭.这里有两种方法. 1.在搭建vue脚手架时提示是否启用eslint检测的. Use ESLint to lint your code? 写 no; 2.如果项目已经生成,我们可以这样. 在项目中代开 bulid 文件夹下的 webpack.base.config.js 文件.将以下代码删掉或注销: { test: /\.(js|vue)$/, loa

  • MySQL数据库远程访问权限如何打开(两种方法)

    下载GPL版本安装 MySQL Community Edition(GPL) Community (GPL) Downloads » 在我们使用mysql数据库时,有时我们的程序与数据库不在同一机器上,这时我们需要远程访问数据库.缺省状态下,mysql的用户没有远程访问的权限. 下面介绍两种方法,解决这一问题. 1.改表法 可能是你的帐号不允许从远程登陆,只能在localhost.这个时候只要在localhost的那台电脑,登入mysql后,更改 "mysql" 数据库里的 "

  • nginx 让users有权限启动的两种方法

    nginx 让users有权限启动两种方法 普通用户在restart和reload nginx时,会报错: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /opt/nginx/conf/nginx.conf:1 我又不能给开发人员root权限,没办法,只好这么做. 原因是:默认情况下Linux的1024以下端口是只有root用

  • Java文件、文件夹权限修改的两种方法

    前言 Java 修改文件权限这个应该是老生常谈的功能,但是最近发现以前写的代码有一点点安全隐患,所以把代码改成NIO的方式,下面会介绍2种修改文件,文件夹权限的方法. 使用File类 这个方式是以前最常见的方式,但是这个方式有点缺点在LINUX或者UNIX系统下,需要显示的指定权限为440,770等就显得不是那么好用了. File dirFile = new File(dirPath); dirFile.setReadable(true, false); dirFile.setExecutabl

  • Vue.js项目中管理每个页面的头部标签的两种方法

    在 Vue SPA 应用中,如果想要修改 HTML 的头部标签,如页面的 title ,我们只能去修改 index.html 模板文件,但是这个是全局的修改,如何为每个页面都设置不一样的 title 呢?下面介绍两种方法. 使用router.meta 在路由里面配置每个路由的地址: routes: [ { /* (首页)默认路由地址 */ path: '/', name: 'Entrance', component: Entrance, meta: { title: '首页入口' } }, {

  • vue中使用WX-JSSDK的两种方法(推荐)

    公司最近有微信公众号的需求,那么微信登录授权和如何使用WX-JSSDk实现分享等等肯定是最头疼的问题.本人也是第一次开发微信公众号,在网上看了很多篇博客,最终选定了两种方法,并且亲测有效. 一.通过全局,在router.afterEach中定义 1.首先通过yarn add weixin-js-sdk/ npm i weixin-js-sdk 2.将微信jsdk挂载到全局上 在utils目录下新建WechatPlugin.js WechatPlugin.js import wx from 'we

  • vue 获取url里参数的两种方法小结

    我就废话不多说了,大家还是直接看代码吧~ 第一种: const query = Qs.parse(location.search.substring(1)) let passport = query.passport; 第二种: var query=this.$route.query; let lat = query.lat; 补充知识:Vue通过query获取路由参数 现在来讲Vue通过query获取路由参数 可以看见com1组件里的路由参数为 name=zhangsan&job=teache

  • MySQL开放远程连接权限的两种方法

    背景: 要求做一个评价系统,由于之前被人做过一小部分,有现成的数据库(数据库:MySQL 5.7 ,数据库软件:MySQL workbench 6.3 CE),为了省去安装数据库导出导入表的麻烦,想要直接远程连接对方数据库. 方法如下: 首先,检查要连接数据库的服务器的防火墙等是否关闭,检查与服务器连接是否通畅(方法:在cmd控制台中 输入 ping ip地址) 其次通过网上查找有两种方法: 1,改表法. 可能是你的帐号不允许从远程登陆,只能在localhost.这个时候只要在localhost

随机推荐