本文是做者最近查閱權限控制相關資料的總結筆記。html
前端路由是所有都由後端返回,仍是後端返回對應角色下的權限,而後前端經過遍歷的方式來修改當前路由呢?
引用上面這個問題的採納答案:前端
第一種後臺返回路由,第二種後臺返回權限。
共同點:兩種方法均可以實現需求
前端都要維護一份路由地址與模塊文件地址的映射
後段返回的數據通常都要再遍歷作二次處理
有關頁面內元素(按鈕)的權限都要另作處理
技術點都會涉及路由守衛和路由鑑權vue差別點:ios
默認路由列表:方法一隻維護home、login等無權限需求路由,其餘路由須要後續經過接口和路由api:addRoutes動態添加;方法二須要維護一個全量的路由列表,不須要額外添加路由,經過配置每一個路由的access數組來作鑑權。
路由跳轉:由於方法一返回的就是該用戶權限下的路由,因此不須要再作權限鑑權;方法二須要。
路由的自定義程度:方法一能夠經過修改數據庫的路由數據來自定義前端的菜單結構,所以也須要作一個實現路由重組的遞歸函數,拓展性更好;方法二針對的是菜單結構相對穩定的項目,通常不支持結構變更。
返回報文:通常來講,返回報文大小 方法一比方法二要大git
總結補充:
第一種是指動態路由,路由是分兩部分,一部分是home、login等無權限需求路由,一部分是由後端返回的該用戶權限下的路由,當用戶登陸後獲得 roles,前端根據roles 去向後端請求可訪問的路由表,從而動態生成可訪問頁面,以後就是 router.addRoutes 動態掛載到 router 上;前端須要有菜單管理,能夠經過修改路由數據來自定義前端的菜單結構,拓展性更好。
第二種是前端配置路由表,後端僅返回權限,前端須要有菜單的權限管理,而且加載路由和菜單時要作權限驗證;該方法是針對菜單結構相對穩定的項目,通常不支持結構變更。github
依據權限實現的按鈕顯隱控制和界面變化:
方法一:v-if數據庫
方法二:自定義指令axios
根據用戶權限判斷各個按鈕的顯示與否,方式無非是v-if或自定義指令,並且只要將v-if背後的權限校驗邏輯抽象成方法,不管是代碼量仍是使用形式上都跟自定義指令幾乎同樣v-if的特色是它會響應數據變化,所以隨着應用的運行會頻繁觸發權限校驗,而權限在應用的整個生命週期內其實只需校驗一次。segmentfault
自定義指令內部仍然是調用全局驗證方法,但優勢在於只會在元素初始化時執行一次,多數狀況下都應該使用自定義指令實現視圖控制。後端
因此,最好是使用自定義指令。
不必定每一個操做按鈕都會發起AJAX請求,好比編輯按鈕自己並不會觸發請求,真正觸發請求的是另外一個保存按鈕。
劃重點:讓按鈕和請求聯繫起來
,好比說按鈕涉及一個名稱爲A的請求,那麼權限指令能夠這樣寫:
<btn v-has="A" @click="Fn">按鈕</btn>
這裏對A的實現能夠有多種形式,好比A能夠是一個包含兩個屬性的對象:
const A = { p: ['put,/menu/**'], r: params => { return axios.put(`/menu/${params.id}`, params) } };
//用做權限: <btn v-has="[A]" @click="Fn">按鈕</btn> //用做請求: function Fn(){ A.r().then((res) => {}) }
利用axios攔截器實現的,目的是將越權請求在前端攔截掉。在請求攔截器中判斷本次請求是否符合用戶權限,以決定是否攔截。在請求發起前集中攔截,這時能夠直接根據請求方法和請求地址來校驗權限。
以axios爲例,攔截器大概長這樣:
axios.interceptors.request.use(function (config) { if(!has(config)){ //驗證不經過 return Promise.reject({ message: `no permission` }); } return config; });
前端路由是所有都由後端返回,仍是後端返回對應角色下的權限,而後前端經過遍歷的方式來修改當前路由呢?