Vue 实现前端权限控制的示例代码


Posted in Javascript onJuly 09, 2019

登录&&权限流程图

Vue 实现前端权限控制的示例代码

前言

首先我们确定的权限控制分为三大部分,其中根据粒度大小分的更细:

  • 登录权限控制
  • 页面权限控制
    • 菜单中的页面是否可以被访问
    • 页面中的按钮 (增、删、改、查)的权限控制是否显示
  • 接口权限控制

一、登录权限控制

登录访问权限控制是对用户的校验。在用户登录成功之后,后台将返回一个token,之后前端每次进行接口请求的时候,都要带上这个token。后台拿到这个token后进行判断,如果此token确实存在并且没有过期,则可以通过访问。如果token不存在或后台判断已过期,则会跳转到登录页面,要求用户重新登录获取token。

做法一

在用户登录成功的回调中将后台返回的token直接存储到localStorage,然后同步配置请求默认参数的形式将token取出放入headers中传给后台。代码如下:

let axiosOptions = {
   method,
   url,
   data,
   timeout,
   // 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'。default json
   responseType,
   // 请求头内追加authToken属性
   headers: {
    authtToken: window.localStorage.getItem(`base/token$$`)
   }
  }

做法二

当前项目中使用axios.interceptors.request.use设置发送请求前的拦截,直接将token塞入req.headers.authToken中,作为全局传入。代码如下:

// axios.interceptors.request.use 请求拦截:配置发送请求的信息
// axios.interceptors.response.use 响应拦截:配置请求回来的信息

axios.interceptors.request.use(req => {
 req.headers.authToken = window.localStorage.getItem(`base/token$$`)
 return req
}, error => {
 return Promise.reject(error)
})

登录涉及到的知识点

  • vuex + localStorage: 本地通过vuex+localStorage持久化存储token(token:服务端创建用于唯一标识用户身份的Key)。
  • axios: 请求拦截验证token,可以使用axios的API:axios.interceptors.request.use,也可以通过添加默认参数的形式在请求头中追加token。

二、页面权限控制

上面已经说到,页面权限控制又分为两种:

  • 菜单中的页面是否可以被访问
  • 页面中的按钮 (增、删、改、查)的权限控制是否显示

先看菜单的页面访问权限

实现页面访问权限又可分为以下两种方案:

  • 方案一、初始化即挂载全部路由,每次路由跳转前做校验
  • 方案二、只挂载当前用户拥有的路由,如果用户通过URL进行强制访问,则会直接进入404,相当于从源头上做了控制

前者的缺点很明显,每次路由跳转都要做一遍检验是对计算资源的浪费,另外对于用户无权访问的路由,理论上就不应该挂载。

后者解决了上述问题,但按需挂载路由就需要知道用户的路由权限,也就是在用户登录进来的时候就要知道当前用户拥有哪些路由权限。

所以肯定是方案二比较符合良好的用户体验。

项目中的菜单权限控制

1.权限涉及到的meta属性

  • noRequireAuth: true 无需权限直接挂载
  • manageFree: true 不在操作权限树中展示

2.router.beforeEach()拦截路由的钩子

  • 不需要权限的路由直接放行。meta内noRequireAuth和manageFree不受权限控制
  • 进入路由前,从后端请求获取需要展示的菜单。后端根据token判断当前用户权限,返回对应菜单。前端递归对比确定最终要显示的菜单列表

3.router.addRoutes()

  • 通过router.addRoutes()动态添加所有符合权限的路由

按钮级权限控制(Vue指令v-permission)

1.每个模块对应有四种权限,查询(get),添加(post),更新(put),删除(delete)
2.利用十进制和二进制来表示当前模块所拥有的权限。1111(15),转换后的二进制与权限的关系表示:从右至左数(1代表拥有该权限,0代表不拥有),第一位代表查询,第二位代表添加,第三位代表更新,第四位代表删除。如eg:二进制1111(15),代表用于查询,添加,更新,删除四种权限。

3.判断对应模块没有此权限时,移除当前按钮dom元素。

使用示例:

<el-button @click="handleClick" v-permission:moduleName.post>新增</el-button>
 <el-button @click="handleClick" v-permission.delete="moduleName">删除</el-button>

三、接口访问权限控制

最后再加上请求控制作为最后一道防线,路由可能配置失误,按钮可能忘了加权限,这种时候请求控制可以用来兜底,越权请求将在前端被拦截。

前后端约定接口采用RESTful风格,同样对应四种权限,包括查询(get),添加(post),更新(put),删除(delete)。对于查询操作,正常如果参数只有一个,应该用get请求,如果有多个参数,需要改为post请求,但是需要在url后面添加/query以告诉服务端当前进行的是查询操作,用于和正常的添加(post)请求区分。同样的是,删除用户时如果有多个参数,DELETE请求同样改为POST请求,在后面添加/delete用于和正常的删除(delete)操作进行区分。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript中yield实用简洁实现方式
Jun 12 Javascript
JS维吉尼亚密码算法实现代码
Nov 09 Javascript
node.js中的http.response.write方法使用说明
Dec 14 Javascript
javascript中attachEvent用法实例分析
May 14 Javascript
手机端页面rem宽度自适应脚本
May 20 Javascript
JS 通过系统时间限定动态添加 select option的实例代码
Jun 09 Javascript
详解angular2实现ng2-router 路由和嵌套路由
Mar 24 Javascript
jquery.onoff实现简单的开关按钮功能(推荐)
May 24 jQuery
vue 中几种传值方法(3种)
Nov 12 Javascript
Vue使用富文本编辑器Vue-Quill-Editor(含图片自定义上传服务、清除复制粘贴样式等)
May 15 Javascript
js实现表单项的全选、反选及删除操作示例
Jun 05 Javascript
element-ui中dialog弹窗关闭按钮失效的解决
Sep 22 Javascript
微信小程序文章详情页跳转案例详解
Jul 09 #Javascript
七行JSON代码把你的网站变成移动应用过程详解
Jul 09 #Javascript
js实现无缝滚动双图切换效果
Jul 09 #Javascript
DatePickerDialog 自定义样式及使用全解
Jul 09 #Javascript
bootstrap 日期控件 datepicker被弹出框dialog覆盖的解决办法
Jul 09 #Javascript
bootstrap datepicker的基本使用教程
Jul 09 #Javascript
JavaScript常用内置对象用法分析
Jul 09 #Javascript
You might like
PHP常用函数小技巧
2008/09/11 PHP
Laravel 5框架学习之向视图传送数据
2015/04/08 PHP
PHP Echo字符串的连接格式
2016/03/07 PHP
discuz论坛更换域名,详细文件修改步骤
2020/12/09 PHP
Jquery 插件学习实例1 插件制作说明与tableUI优化
2010/04/02 Javascript
js 实现css风格选择器(压缩后2KB)
2012/01/12 Javascript
js数组去重的常用方法总结
2014/01/24 Javascript
利用jquery动画特效和css打造的侧边弹出垂直导航
2014/04/04 Javascript
基于jQuery实现多标签页切换的效果(web前端开发)
2016/07/24 Javascript
vue中使用refs定位dom出现undefined的解决方法
2017/12/21 Javascript
js+css实现打字效果
2020/06/24 Javascript
微信小程序中使用自定义图标(阿里icon)的方法
2018/08/20 Javascript
零基础之Node.js搭建API服务器的详解
2019/03/08 Javascript
基于AngularJS拖拽插件ngDraggable.js实现拖拽排序功能
2019/04/02 Javascript
JS实现图片幻灯片效果代码实例
2020/05/21 Javascript
Vue之封装公用变量以及实现方式
2020/07/31 Javascript
vue在图片上传的时候压缩图片
2020/11/18 Vue.js
[47:45]Liquid vs OG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
[01:07:13]TNC vs Pain 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
浅析Python中的序列化存储的方法
2015/04/28 Python
Python中字符串的常见操作技巧总结
2016/07/28 Python
Python实现句子翻译功能
2017/11/14 Python
通过python顺序修改文件名字的方法
2018/07/11 Python
如何基于Python制作有道翻译小工具
2019/12/16 Python
python3光学字符识别模块tesserocr与pytesseract的使用详解
2020/02/26 Python
python pandas利用fillna方法实现部分自动填充功能
2020/03/16 Python
python实现梯度下降法
2020/03/24 Python
Tensorflow tf.tile()的用法实例分析
2020/05/22 Python
浅谈移动端网页图片预加载方案
2018/11/05 HTML / CSS
澳大利亚电商Catch新西兰站:Catch.co.nz
2020/05/30 全球购物
简述使用ftp进行文件传输时的两种登录方式?它们的区别是什么?常用的ftp文件传输命令是什么?
2016/11/20 面试题
2014年廉洁自律承诺书
2014/05/26 职场文书
2015年护士工作总结范文
2015/03/31 职场文书
go语言map与string的相互转换的实现
2021/04/07 Golang
HTML中的表单元素介绍
2022/02/28 HTML / CSS
Python3的进程和线程你了解吗
2022/03/16 Python