基于Vue2.0实现后台管理系统权限控制
本文参考了基于Vue实现后台系统权限控制一文,细说自己在使用Vue2.0实现权限控制过程中的认识。
任何一个后台管理系统,都绕不开对权限控制的需求。以前ASP.NET的时代,权限控制都是通过重写Controller
类中的OnActionExecuting
方法,或者重写AuthorizeAttribute
特性类的OnAuthorization
方法等,来实现对权限的控制。
但是到了ASP.NET Core,尤其是前端采用Vue框架的以后,突然之间有点适应不过来了,特别是菜单的显示,已经不是以前后台渲染视图的实现方式了。
在我看来所谓的权限控制,其本质就是对用户发起请求的控制。用户有没有权限,其实就是能不能发起请求。只有在权限系统中,给用户分配过相应的请求权限,用户才能请求到相应的资源,否则就会被拦截。我们通常所说的权限,又可以细分为菜单以及按钮权限。菜单是对页面的请求,按钮是对资源的请求,资源可以理解为增删改查。
Vue菜单权限控制
先来说说如何实现Vue的菜单权限控制。Vue是单页面应用,通过路由来实现页面的变换。菜单权限的控制其实就是路由权限的控制。实现路由控制的一个简单方法就是在路由的before钩子里检验当前即将跳转的路由地址是否有权访问,伪码:
1 | router.beforeEach((to, from, next) => { |
这种做法只适用于路由不多的系统,因为它有两个致命的缺点:
- 路由组件必须全部注册后才能使用,无法按序加载,如果遇到组件很多的情况下,应用将加载大量的冗余代码
- 每次跳转都要遍历一次完整的路由,浪费性能
理想的实现方式是在程序启动时,只初始化一个具有登录以及错误页面路由的Vue应用。随着用户登录拿到权限后,用菜单权限筛选出可用的路由,然后router.addRoutes()
动态添加路由。如此一来就可以实现菜单权限的控制了,伪码:
1 | let user = sessionStorage.getItem('user'); |
前端使用element-ui菜单组件实现菜单渲染,伪码:
Vue按钮权限控制
按钮权限控制与菜单权限控制的实现思路类似,按钮的本质其实就是请求。如何控制按钮的显示与否呢?可以通过v-if
或者自定义指令实现。原作者推荐使用自定义指令,理由我直接引用过来
v-if
的特点是它会响应数据变化,因此随着应用的运行会频繁触发权限校验,而权限在应用的整个生命周期内其实只需要校验一次。为了避免无谓的程序执行,这里可以用自定义指令来实现
伪码如下:
1 | Vue.directvie('has',{ |
has()
方法就是权限的校验方法,将该方法全局混合到Vue对象中,使得应用里的每个组件都可以访问到这个方法。伪码如下:
1 | let has = function(permission){ |
permissions
属性用来确定是否拥有资源权限,效率高于遍历原始权限数组。
另外还可以为axios
请求设置拦截器,作为权限控制的第二道防线,伪码:
1 | axios.interceptors.request.use(function (config) { |
这个拦截器很有必要,试想按钮如果还有回调请求的话,光配一个按钮权限是不够的。
总结
我说的没有原文详细,但是大致思路摆在这里,如果想要深入原理的朋友,还是欢迎去原作者的博客学习学习。
虽然这个基于Vue的权限控制方案设计得很巧妙,但是也不是完美无缺的,归根结底所有的操作都是在前端判断,在前端也就意味着,如果黑客想绕过前端权限控制的话也是有可能的,比如手动注入登录以后返回的用户权限。个人觉得还是在后端判断权限更稳妥一点,至少被修改的可能性几乎为零。但是作为拓宽思路的一种设计,应用于不是对于安全性极其严格的场景,不失为一种好的方案。