使用Angular指令+服务实现权限控制
公司已有的代理商管理系统,权限控制需要调整,我负责前端相关工作,此文记录一下修改过程。
原有实现
前端原有的权限控制是基于角色的,即根据当前登录账号的角色,控制菜单及功能入口的显示/隐藏状态。前端主要用到框架Angular和Angular-ui-router,在这前提下,原有的权限控制实现方式大致如下:
在
mainController
中获取当前登录用户的角色,并将其赋值到$rootScope.role
,页面中根据该变量做基于角色的权限控制。具体实现即使用ng-show="role === ?"
控制元素显示/隐藏,达到不同角色显示不同内容的效果
上述实现的最大问题在于前端权限控制严重依赖系统固有角色,极度僵硬,角色变动会给前端带来巨大冲击。原有的丑陋实现之所以能够存在,跟技术人员的水平有一定关系,同时也因为系统初期相对简单,只包含3个角色(root、agent、user),才没有暴露出问题。随系统功能增加,角色与权限都需要再细分,按照之前的实现方式,很难维护,不得已才重新设计与实现前端的权限控制。
同时由于历史原因,存在这样一种情况:
本是相同性质的接口,却按角色不同,拆分成了不同接口。比如日志查询,root调用的是
/logs/findAllLogs
,agent调用的是/logs/findAgentLogs
这是系统设计时犯的一个错误,分权分域,域和权的混淆。为处理上述不同角色调用不同接口的情况,在其他controller
中也经常也需要使用变量$rootScope.role
,因此在这些controller
中依赖角色信息的代码,需要等待mainController
中角色信息获取成功后方可执行。
新方案
要解决前端权限控制僵硬的问题,核心就是权限控制不应依赖角色,而是依赖登录账号所拥有的权限项,这需要后台做两个修改:
- 提供接口获取当前登录账号的权限项
- 因分权分域混淆,导致同性质接口出现多个的情况,需要将多个接口合并为一个接口
后台配合修改后,接下来考虑前端实现,实现方式完全可以参照原有实现,只需要将角色概念替换成权限项。在mainController
中获取账号权限项,赋值给$rootScope