权限动态管理
一般后台权限动态管理基于RBAC基于角色的访问控制官方标准实现,先由后端定义角色和系统全量菜单,再通过角色授权为不同角色分配不同菜单权限。用户登录时,后端根据其角色返回对应的权限菜单。路由是组件的映射关系,分为常量路由和权限路由,初始化创建路由实例时始终以常量路由为基础,权限路由是支撑所有功能的全量路由,新增功能只需扩展这个全量权限路由即可。
接下来我们根据后端返回的权限菜单,对全量权限路由做减法筛选,只保留当前角色有权限的路由,再通过Vue Router实例的addRoute方法,把筛选后的动态权限路由添加进去,这样就实现了不同角色对应不同菜单的权限控制。
刷新页面报404,是因为刷新会重新加载JS文件,此前动态添加的路由会丢失。我们将后端返回的权限菜单码缓存到sessionStorage,刷新后数据不会丢失,且权限路由是前端文件本身也不会丢失。所以在路由入口文件中,我们判断若缓存的权限菜单存在,就重新执行路由筛选、addRoute动态添加的逻辑,这个处理方法统一放到Vuex的Action里,再配合全局路由守卫,用户已登录且动态路由重新添加完成后直接放行,跳转到对应菜单页面,以此解决刷新404问题,实现权限的刷新保持。
另外,路由处理逻辑要放在Vuex的Action里,并非因为有异步请求,而是调用addRoute修改了全局路由实例,这属于副作用操作;而Vuex的Mutation只能做纯同步的State数据修改,不允许有任何外部副作用,所以即便只是纯前端的比对筛选操作,也必须放到Action中。且这个Action是纯前端操作,不会出现失败的情况,就算不手动return Promise也可以,因为Vuex的Action本身会自动返回一个Promise实例,默认是成功状态;若后续有失败场景,再手动return新的Promise控制成败即可。