今天被问到关于前端权限的事,具体问的是,怎么根据用户权限动态生成路由,一时答不上来,因为我们目前项目关于前端一级菜单权限,是在主页面渲染前。create中得到当前用户的permision,根据其permission判断哪些一级菜单给予展示,哪些一级菜单不予展示。
然后就查了一下,前端权限控制的问题。
总结下来主要分为以下四种权限的情况:
一、接口权限
接口权限最简单,目前一般采用jwt的形式来验证,没有通过的话一般返回401 Authentication Required, 返回登录页重新登录
登录完拿到Token
,将token存起来(cookie或者ssessionStorage),每次登录的时候头部携带token就行了(axios请求拦截器实现)。
伪码实现
1 | const {token} = login() |
二、按钮权限
一个页面会有创建、删除、更新、编辑等按钮。不同用户应该是有不同的权限,例如:普通用户权限、管理员权限、自定义权限等。
假设:我们定义权限码0:不可见,1:不可编辑,2:可编辑。
根据后端返回的按钮权限列表。然后我们根据权限列表使用v-if指令,或者使用disabled属性达到相应权限效果。(这边最好自己写一个自定义指定,例如:v-permission)
伪码实现
比如概览页面的编辑按钮 名字先和后端定义好叫做overview-edit
1 | // overviwe.vue overview是概览页面的路由名 |
三、页面权限
在我看来页面权限就是菜单权限,如果说我们在UI上没有点击去那个页面的按钮其实就是没有那个页面的权限。
一句话,获取菜单权限列表,动态递归生成菜单
这个菜单权限的列表可以是后台直接返给你的,也可以是你注册路由的时候写在meta里面的菜单信息,后端返回路由权限,你根据meta信息动态算出菜单权限。
伪码实现
1 | //如果是定义在route信息里面会是这种样子 |
四、路由权限
上面的菜单权限虽然做到能看不见菜单,但是我可以通过直接输入url的方式去没有权限的页面呀,这种情况需要靠我们的路由权限
来阻止。
这里有两个方案
第一种,也是我目前项目用的,先注册好所有的路由,然后获取有资格访问的路由权限列表,最后直接通过Router.beforeEach来判断,每次跳路由的时候判断是否在权限列表里,在的话就放行,不在就提示权限不够
优点:简单暴力,不会跳到404页面(因为去的路由能在路由规则里找到)
缺点:由于初始化了所有路由,运行的时候会挂载不必要的路由(?有待考究)
第二种,先只注册基本路由,然后获取路由权限列表,然后借助route.add() API根据权限列表将有权限的路由动态注册到路由规则上
优缺点与第一种正好相反
伪码实现
这里只写第一种方案,第二种大家自行google
1 | const {routeAuthList} = login() |
- 本文作者: gtt
- 本文链接: https://gtt011029.github.io/posts/13126/