《看完就懂系列》項目中的權限管理複雜嗎?

這是大冰塊2021年第5篇原創文章,和大冰塊一塊兒在前端領域努力吧!!!💪前端


寫在前面

還記得在我入門沒多久的時候,第一次接觸公司中大型項目的時候,項目權限這塊把我搞的很懵。大概是個人邏輯思惟不夠強大,猛然接觸新的思惟方式總是轉不過彎來。不過功夫不負有心人,靠着前輩的指導和本身一點點摸索,總算對權限的總體流程(前端方面)有了一個基本的掌握。後端

現在回首再看,前端方面的權限管理其實沒什麼難度,就像一把鑰匙開一把鎖,只要把一一對應的邏輯關係作好就能夠了。由於思路是類似的,因此實現的代碼都是大同小異,所以本文主要以文字和邏輯圖爲主。數組

今天就來談一下 項目權限 這一塊,儘可能談的簡單一些,讓前端小白都能明白,同時也詳細說下 權限管理禁止容許 的思路,歡迎你們一塊兒討論更好的方法,也但願拋磚引玉,能有大神來指出不足與更好的改進方法。😜緩存

什麼是權限管理

簡單來講,就是不一樣的用戶具備不一樣的權限:服務器

用戶A進入頁面,頁面內有增長查找兩個選項,markdown

用戶B進入頁面,頁面內有增長查找修改刪除四個選項,網絡

用戶C進入頁面,頁面提示權限不足,3秒後將跳轉首頁異步

那麼若是咱們有100個用戶,難不成要給他們搞100套權限嗎???post

固然不是,用戶並不直接對應權限,用戶對應的實際上是角色學習

也就是說:用戶對應角色,角色對應權限。若是咱們有一百個用戶,可是他們等級不一樣,老闆有所有的權限,經理有80%權限,組長有50%權限,職員有20%權限。

那麼其實咱們只須要4個角色:老闆角色 有所有的權限,經理角色 有80%權限,組長角色 有50%權限,職員角色 20%權限。

用戶只要對應這4個角色便可,不一樣級別的用戶就能有不一樣的權限了。

值得注意的是:

用戶和角色的對應能夠是單對多的 ,一個用戶能夠有多個角色,好比用戶小明是經理,但他可能臨時兼職一個組長,因此他對應的角色是經理+組長

角色和權限的對應也是單對多的 ,一個角色不必定只有一個權限,這個角色可能具備所有的權限(增刪改查等),也可能只有一部分權限(增刪)。

上面的說明能夠改爲這樣:

用戶A進入頁面,用戶A對應的角色是職員,全部職員角色進入頁面,頁面內都會有增長查找兩個選項,

用戶B進入頁面,用戶B對應的角色是組長,全部組長角色進入頁面,頁面內都會頁面內有增長查找修改刪除四個選項,

用戶C進入頁面,用戶C沒有對應的角色,沒有對應角色的用戶進入頁面,頁面都會提示權限不足,3秒後將跳轉首頁

權限管理的邏輯圖

文字說明可能有不到位的地方,下面咱們來用流程圖的形式來更直觀的表現一下權限管理的邏輯。

頁面權限邏輯圖

在路由攔截中判斷當前用戶是否具備對應的頁面路由權限。

大冰塊辛辛苦苦畫的圖1

★功能權限邏輯圖

在頁面渲染前,判斷當前用戶是否具備當前頁面某功能的權限,決定是否渲染。

後端要對權限作二次鑑權處理,避免頁面渲染錯誤或者緩存問題,致使功能權限顯示,從而誤操做。

大冰塊辛辛苦苦畫的圖2

★數據權限共享邏輯圖

數據權限共享本質上是新加了一個臨時角色,把臨時角色加給被分享者便可。

同時,臨時角色應當記錄自身建立時間,過時時間,分享者ID以及被分享者的ID,方便後期統計溯源。

大冰塊辛辛苦苦畫的圖3

權限管理的代碼實現

代碼實現通常是經過路由攔截請求攔截共同實現,由於不一樣的項目代碼結構可能有所不一樣,因此以下代碼只是思路的一個延展說明,並不能直接拷貝到項目中使用哦~

// 路由攔截

 // name 要前往的路由
 // access 用戶權限數組
 // routes 路由列表
 const canTurnGo = (name, access, routes) => {
	const routePermission = (list) => {
		return list.some(item => {
			if (item.children && item.children.length) {
				return routePermission(item.children)
			} else if (item.name === name) {
				return hasAccess(access, item)
			}
		})
	}
	return routePermission(routes)
 }
 ...
 
 // 請求攔截
 // 在攔截到http狀態碼非200時調用的方法
 const errorHandler = function(error) {
    const codeMap = {
        200: '服務器成功返回請求的數據',
        201: '新建或修改數據成功',
        202: '一個請求已經進入後臺排隊(異步任務)',
        204: '刪除數據成功',
        400: '發出的請求有錯誤,服務器沒有進行新建或修改數據的操做',
        401: '用戶沒有權限(令牌、用戶名、密碼錯誤)',
        403: '用戶獲得受權,可是訪問是被禁止的',
        404: '發出的請求針對的是不存在的記錄,服務器沒有進行操做',
        406: '請求的格式不可得',
        410: '請求的資源被永久刪除,且不會再獲得的',
        422: '當建立一個對象時,發生一個驗證錯誤',
        429: '請求次數超出當天上限',
        500: '服務器發生錯誤,請檢查服務器',
        502: '網關錯誤',
        503: '服務不可用,服務器暫時過載或維護',
        504: '網關超時',
    }
    const {response} = error
    if (response) {
        // 獲取http狀態碼對應的錯誤信息
        const errorText = codeMap[response.status] || response.statusText
        // 若是某個狀態碼要執行特殊操做,則:
        if(status === 403){
            throw new Error(errorText)
        }else{
            throw new Error(errorText)
        }
    } else {
        notification.error({
            description: '您的網絡發生異常,沒法鏈接服務器',
            message: '網絡異常',
        })
    }
    return
}
複製代碼

總結

相似於這種權限管理,最重要的仍是考慮問題的思路,有了正確的思路轉化爲代碼就很容易了。

按照權限-角色-用戶的管理方式,後期權限的維護以及增刪改查均可以放在前端來處理,後端只要配置一次就能夠再也不操做了。避免了後端代碼在權限管理的邏輯雜亂,很差維護等問題。簡單來講,每一個權限都有一個惟一的id,用戶登陸後去判斷用戶對應的角色是否對應有某權限的id,做爲判斷用戶是否具備某權限的標準。若是新增一個頁面,裏面有n個功能權限,只需把路由地址以及加入到路由權限表中,把n個功能權限添加到功能權限表中,再給角色分配對應權限便可。

這種公共的權限管理,每一個項目根據不一樣的需求都有本身的處理方式。另外,權限管理也能夠作成公共的組件,新建項目時引入配置便可,此處暫不作討論了。

寫在後面

這是大冰塊《看完就懂系列》的第4篇文章,《看完就懂系列》旨在把一些常見的概念或方法以通俗易懂的方式呈現出來。歡迎你們點擊其餘文章一塊兒討論學習:


原創不易,若有錯誤,歡迎指出。

若是有幫助到你,請給大冰塊來個三連(點贊收藏評論),讓咱們一塊兒在前端的路上進步吧~🤭

相關文章
相關標籤/搜索