实现前端权限控制
什么是前端权限控制
最简单的理解就是,不同的用户看到的前端界面是不同的。实现的整体逻辑,是前端先发出请求,从后端获取权限码,通过权限码对整个应用页面的展现内容以及导航逻辑进行控制,从而达到权限控制的目的,前端做的权限控制也算是提供一层防护。
为什么要做前端权限控制
前后端是相辅相成的,前后端权限各自的控制对象、控制目的和控制手段都不一样,在实际项目中,前端权限控制也有其不可或缺的作用和业务需求,比如
- 提搞权限的控制,增加安全性;
- 过滤越权请求,减轻服务端压力;
- 提升用户体验;
- 根据后端权限配置动态显示前端视图的展示;
- 根据后端权限配置动态管理界面导航菜单。
怎么实现前端权限控制
前端权限归根结底是请求的发起权,请求的发起可能由页面加载触发,也可能由页面上的按钮点击触发。
总的来说,所有的请求发起都触发自前端的路由或页面的元素,所以要从这两方面进行权限控制,最终要实现的目标是:
- 页面元素的权限控制,比如某一个按钮的显隐。
- 前端路由的权限控制,比如用户访问到没有权限的路由地址时跳转403提示页面。
- 导航菜单的权限控制,比如用户只能看到自己有权看到的导航菜单。(这里导航菜单的权限其实也可以归为页面元素,但其又跟前端路由息息相关,而且业务上会有这部分的配置,所以我就把它抽出来单独处理。)
具体实现方案
首先是前后端对权限控制的交互问题。因为要实现可通过权限配置动态管理前端试图展示的需求,所以前端会有一个json的文件用于配置整个前端资源树,导航菜单根据这个前端资源树进行构建的,后端则是根据这个配置文件生成树形的数据进行存储,每个前端元素对应一个权限码,前端向后端发出请求,获取用户拥有的权限码,再根据用户的权限码进行视图的展示。
然后是前端从权限控制和权限存储这两个大方面考虑前端权限的实现问题。 因为前端工程的技术框架是 next.js ,所以有些考虑和实现的方法会有所不同。
权限存储有三种方式:
-
引入状态管理插件(redux、dva…)
-
存储在 sessionStorage 、localStorage 等。
-
不做存储,每进入一个页面都重新请求权限。
第一种方式改动成本大,第二种方式涉及安全性,最后选择第三种方式。
权限控制分为三个点去考虑:
-
页面元素的权限控制
-
实现自定义权限判断hook
-
实现自定义权限判断组件
由于自定义权限判断组件对于现有的前端工程来说改动成本较大,不方便拓展,植入性比较差,所以选择了第一种方式。如果想选第二种方式,可以参考 react高阶组件之经典应用:权限控制
-
-
前端路由的权限控制
-
router.beforePopState
-
在 next.js 的服务端判断权限,重写路由
第一种方式失败了,因为beforePopState只有在浏览器前进后退行为下才会触发,原因点击(这里)[https://github.com/vercel/next.js/issues/4809] 所以选择第二种方式。
-
-
导航菜单的权限控制
-
在 next.js 的服务端更改前端资源树配置文件
-
更改配置菜单数据存储方式
-
在 next.js 的服务端获取权限数据,动态生成导航菜单
第一种方式失败了,因为 next.js 无法自动刷新,第二种方式改动成本比较大,也放弃。 最后当然是选了第三种方式。
-
接着是前端资源树数据结构的设计,因为导航路由是根据前端资源树动态生成的,所以也要把相对应路由的考虑进去,如下:
资源树和路由的控制逻辑如下: