在做商家後臺管理系統時,作為前端通常會設計到大量的權限控制問題,按照細粒度歸歸類大致可以分類以下三類
- 頁面權限
- 模塊權限-頁面區塊(組件)是否顯示
- 元件權限-組件內元素是否顯示
以往的處理方式
後端會將用戶權限數據同步注入到VM模板中或者前端發送異步請求取到權限數據,數據消費場景一般都散落在代碼的角角落落。
用這種方式實現的代碼,執行上沒有問題,也達到了業務的需求。但是隨著代碼量的遞增,代碼變得難以維護,特別是新接手的同學,簡直是一場噩夢。
React體系下的實現方式
頁面權限、模塊權限、元件權限三種前端權限表現形式對應不同的管理策略。
頁面權限
對於傳統的多頁應用,頁面權限控制不需要前端關心,後端路由做一層控制。在SPA架構的前端應用中,我們的思路是將所有的前端路由配置在後端,對於不同角色的用戶,後端把路由列表吐給前端註冊。
模塊權限、元件權限
對於這兩類權限控制的事就全部需要交給前端處理了,大致思路是將系統中用戶散落的權限統一配置,通過HOC包裝一下React組件,提供劫持渲染和權限透傳的能力。
統一管理權限registerAuthRules
應用的所有權限配置會被統一配置在一個閉包中,權限的值支持後端同步吐出,也支持每次異步獲取(利用Promise實現)
權限規則表達式
權限列表中配置的只是顆粒度最細的單個權限。在實際業務需求中,我們常需要根據權限格則組合結果,決定是否顯示。比如ComponentA的顯示條件是isX1 && isX2 或者 isX1 || isX3。
這裡需要引入權限規則表達式的概念。How to compute?
第一步:利用詞法分析器解析出表達式中有多少個權限變量。利用esprima可以輕鬆取到
第二步:計算每個變量對應的權限值
第三部:計算規則表達式,因為權限規則有可能是異步或者的,這裡將每個格則包裝成Promise對象,利用Promise.all做統一返回,在成功的回調函數中通過New Function的方式計算字符串表達式的結果
如何使用
registerAuthRules
註冊權限規則列表,支持同步規則和異步規則
參數:
- rules {Object} 應用權限規則MAP
registerComponentRules
註冊組件顯示規則,根據組件displayName配置組件所需權限列表
參數:
- rules {Object} 組件權限規則MAP
調用查看
Auth HOC函數
參數:
- options {Object} 組件權限規則MAP
- options.placeholder {Component} 組件隱藏時的佔位節點;默認為noscript
- options.initialHide {Boolean} 當存在異步權限規則時,組件是否先默認隱藏;默認值為true
- options.rules {Object} 配置組件需要權限規則集合,作為props屬性$auth傳遞給組件
1. 組件級別權限控制
根據WrappedComponent.displayName判斷組件是否有權限
2. 組件內部權限控制(權限屬性模式)
代碼實現hoc-auth https://github.com/amibug/hoc-auth
閱讀更多 阿里云云棲號 的文章