先后端分离模式下,全部的交互场景都变成了数据,传统业务系统中的权限控制方案在前端已经再也不适用,所以引起了我对权限的从新思考与设计。前端
权限控制到底控制的是什么?git
在理解权限控制以前,须要明白两个概念:资源和权限。什么是资源,对于一个系统来讲,系统内部的全部信息均可以理解为这个系统的资源。页面是资源、数据是资源、按钮是资源、图片是资源、甚至页面上一条分割线也可理解为是这个系统的资源。而权限就是访问某个资源所须要的标识。不管系统的权限如何设计,在用户登陆时,均可以计算得出用户所拥有的权限标识集合,也就肯定了该用户能访问哪些系统资源,这就是我理解的权限控制的本质。因而咱们能够得出:权限控制是控制登陆用户对于系统资源的访问。github
先后端分离模式下,先后端在权限控制中各自的职责是什么?后端
在弄清先后端在权限控制中各自的职责是什么以前,须要理解先后端各自在系统中的职责。这个仍是很好理解:安全
因为前端负责与用户交互,用户所能操做的资源入口都是由前端进行控制,那么前端的权限控制就包括:前后端分离
随着前端组件化的快速发展,用户所看到的一切都可理解为组件,页面是个大组件,其内部由各个小组件拼凑而来,那么前端权限控制最终落地到对组件的权限控制。因而脑补了出了最优雅的权限组件使用方式:ide
<组件 permissionName='xxx' />
前端能够渲染出用户权限范围内的各类系统资源,可是不能保证数据接口的安全性,某些比较喜欢折腾的用户彻底能够越过前端的页面访问咱们系统的数据接口,那么服务端的权限控制最终落地到对接口的权限验证。组件化
实现思路测试
引上文,系统的一切资源都可进行权限控制,实际上也能够作到,但在咱们实际的操做过程当中,每每不须要细化到分割线那种程度。这里以按钮级权限控制为例作实现说明,若是有更细粒度的权限需求,此思路依然可行。ui
let hasPermission = permission.check(current.permissionName); <div className={styles.content}> {hasPermission ? children : <Exception type={403}/>} </div>
<BirdButton permissionName={'sys'} type='primary'>测试按钮</BirdButton>
public class SsoAuthorizeInterceptor extends HandlerInterceptorAdapter { @Autowired private TicketHandler ticketHandler; @Autowired private SsoAuthorizeManager authorizeManager; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (!(handler instanceof HandlerMethod)) return false; HandlerMethod handlerMethod = (HandlerMethod) handler; SsoAuthorize authorize = handlerMethod.getMethodAnnotation(SsoAuthorize.class); if (authorize != null) { TicketInfo ticketInfo = ticketHandler.getTicket(request); if (ticketInfo == null) { throw new UnAuthorizedException("用户信息已失效."); } String[] requirePermissions = authorize.permissions(); if(requirePermissions.length==0)return true; boolean isCheckAll = authorize.isCheckAll(); UserPermissionChecker permissionChecker = authorizeManager.getUserPermissionChecker(); if(!permissionChecker.hasPermissions(ticketInfo.getUserId(),requirePermissions,isCheckAll)){ throw new ForbiddenException("用户没有当前操做的权限."); } } return true; } }
源码地址
本博客涉及到的前端权限控制思路均已在https://github.com/liuxx001/bird-front项目中实现,项目中除了按钮级权限方案还提供了后台业务系统开发中经常使用的数据组件,包括:
全部业务组件的理念均是结合服务端接口进行组件的封装,兼顾灵活性的同时保证更优的业务开发速度。