视频学习链接(推荐):
前端面试官必问系列-后台系统的权限控制与管理【完结】_哔哩哔哩_bilibili课程内容介绍:权限只有后端才需要考虑? No! 前端一样能发挥重要作用!本堂课教你通过前端技术实现后台权限的管理和控制。课程核心技术点:权限概念,登录拦截,响应拦截,动态路由,自定义指令https://www.bilibili.com/video/BV15Q4y1K79c?from=search&seid=10381782027905589124
Vue权限控制
在Web系统中,权限很久以来一直都只是后端程序所控制的,为什么呢?因为Web系统的本质围绕的是数据,而和数据库最紧密接触的是后端程序所以在很长的一段时间内,权限一直都只是后端程序需要考虑的话题,但是随着前后端分离架构的流行,越来越多的项目也在前端进行权限控制。
1.权限相关概念
1.1.权限的分类
后端权限
从根本上讲前端仅仅只是视图层的展示,权限的核心是在于服务器中的数据变化,所以后端才是权限的关键,后端权限可以控制某个用户是否能够查询数据,是否能够修改数据等操作
前端权限
前端权限的控制本质上来说,就是控制前端的视图层的展示和前端所发送的请求,但是只有前端权限控制没有后端权限控制是万万不可的前端权限控制只可以说是达到锦上添花的效果。
1.2.前端权限的意义
如果仅从能够修改服务器中数据库中的数据层面上讲,确实只在后端做控制就足够了,那为什么越来越多的项目也进行了前端权限的控制,主要有这几方面的好处
降低非法操作的可能性
不怕贼偷就怕贼惦记,在页面中展示出一个就算点击了也最终会失败的按钮,势必会增加有心者非法操作的可能性
尽可能排除不必要请求减轻服务器压力
没必要的请求,操作失败的请求,不具备权限的请求,应该压根就不需要发送,请求少了,自然也会减轻服务器的压力
提高用户体验
根据用户具备的权限为该用户展现自己权限范围内的内容,避免在界面上给用户带来困扰,让用户专注于分内之事
2.前端权限控制思路
2.1.菜单的控制
在登录请求中,会得到权限数据,当然,这个需要后端返回数据的支持前端根据权限数据,展示对应的菜单.点击菜单才能查看相关的界面.(不同用户的菜单列表不一样)
2.2.界面的控制
如果用户没有登录,手动在地址栏敲入管理界面的地址,则需要跳转到登录界面
如果用户已经登录可是手动敲入非权限内的地址,则需要跳转404界面
2.3.按钮的控制
在某个菜单的界面中,还得根据权限数据,展示出可进行操作的按钮,比如删除,修改,增加
2.4.请求和响应的控制
如果用户通过非常规操作,比如通过浏览器调试工具将某些禁用的按钮变成启用状态,此时发的请求,也应该被前端所拦截
3.实践:
1.菜单的控制
一般来说,菜单的控制都会让后端在登录请求后存放在res.rights中,权限数组中的authName和children中的authName对应的就是用户所拥有的权限菜单
在用户进行登录的时候,将权限列表保存到vuex中
在vuex中定义一个mutation来对rightsList进行保存
在home.vue中先对state映射成计算属性
在create生命周期中将获取的rightsList存放到data中的menulist中给菜单组件渲染(假如后端返回的数据不能直接给rightsList展示,可以在这里对返回的数据处理成方便渲染的数据)
问题:当我们将渲染菜单的数据存放在vuex中的rightsList时,页面一刷新vuex中的数据会被清空,这时我们又没有到登录界面去登录所以没有将数据存放在vuex中。会造成一刷新页面菜单栏为空的现象
解决方法:
登录时将权限内容保存到sessionStorage中(sessionStorage中存放的是字符串)
通过sessionStorage.getItem去获取rightsList中的内容
此时刷新页面菜单能正常显示
同理,点击登录按钮将用户名保存到sessionStorage中
点击退出登录按钮清空sessionStorage中的内容 并且让页面重新刷新(清空vuex中的内容)
2.界面的控制
在登录后可以将token保存起来
利用路由导航守卫对有无登录做出对应页面跳转
重点:动态路由的渲染
不同的用户有不同的权限,如果路由写死了,那么就算没有权限的用户也可以通过修改url路径来访问权限之外的路由页面
将我们的路由规则注释掉
将路由规则提取成变量
每一个路由规则都有一个变量俩映射,这个变量是后端返回的对应路由的path
使用router.options.routes可以获取当前的路由规则
使用router.addRoutes()可以更新修改后的路由规则
当用户点击登录后就可以对动态路由进行初始化
BUG: 如果我们此时刷新页面,会发现其他权限也无法访问,这是因为刷新页面后对于router.js也刷新了,那么添加的动态路由就不存在
解决: 我们可以通过在APP.Vue文件中create生命周期来初始化动态路由
3.按钮的控制
虽然用户可以看到某些界面了,但是这个界面的一些按钮,该用户可能是没有权限的.因此,我们需要对组件中的一些按钮进行控制.用户不具备权限的按钮就隐藏或者禁用,而在这块中,可以把该逻辑放到自定义指令中 permission.js
通过Vue.directive创建自定义指令
inserted()是元素插入dom节点时触发,其中el是指当前的元素,binding是获取自定义指令中的数据内容
在渲染动态路由时就有将路由对应的权限保存在meta中。此时再判断自定义指令中是否存在当前路由的meta中的权限,如果没有那么移除权限,如果有并且自定义指令中有disable那么可以让元素不可选中。
在v-permission中使用自定义指令
需要在main.js中引入
4.请求和响应的控制
请求控制
除了登录请求都得要带上token,这样服务器才可以鉴别你的身份
对请求的类型进行映射,如果我们对没有权限的按钮在页面中修改他可以使用,那么发送请求的时候也需要把它拦截下来。
这时候就需要我们存放在meta中的权限
让存放的权限和请求类型做比较,如果一致那么可以发送,如果不一致那么发送不了
同样对响应的数据进行控制,如果返回的code是401说明没有token,或者token有错误,那么对他进行重定位到登录页面