先後端分離模式下,全部的交互場景都變成了數據,傳統業務系統中的權限控制方案在前端已經再也不適用,所以引起了我對權限的從新思考與設計。前端
權限控制到底控制的是什麼?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項目中實現,項目中除了按鈕級權限方案還提供了後臺業務系統開發中經常使用的數據組件,包括:
全部業務組件的理念均是結合服務端接口進行組件的封裝,兼顧靈活性的同時保證更優的業務開發速度。