先後端分離下前端權限處理

權限在我看來指的是某個用戶是否可以訪問某個接口。對應到前端,即便某個用戶訪問了一個本不該該讓他看到的頁面,在訪問接口時不具有權限,這樣即便進入了頁面,也不能看到相應的數據。可是咱們前端要作的工做就是讓用戶在訪問這個頁面的時候,直接就收到提示,沒有權限。javascript

但如今許多項目中頁面路由都是由前端去管理了,如何作到這一點呢,接下來我就分享一下在過往項目中我所用的方案。前端

我寫了demo,上傳到了github上,地址爲:admin-permission-demovue

數據庫表是怎樣設計的

一開始與後端去對接這個需求的時候,我是感到很懵逼的,以爲無從下手。由於我根本就不知道權限控制是怎麼去作的,也不知道權限其實就是限制用戶對於接口的訪問。因此開始以前我以爲有必要說一下,權限表是怎樣設計的。 咱們項目中所使用的是 RBAC ,其實很簡單,就是有這麼三個東西:用戶、角色、權限(資源)。圖我就懶得畫了,省事兒直接用一個別人畫好的圖。java

權限

這個權限就是項目中的接口,意思就很明顯了。給角色規定了可以訪問哪些接口,而後給用戶分配了角色。這樣就能控制用戶哪些接口能訪問,哪些接口不能訪問。react

菜單權限與按鈕權限

咱們項目中權限表的大概的樣子:git

id p_id type permission name
主鍵ID 父級ID 類型:菜單或按鈕 權限標識 名稱

權限又分爲菜單權限和按鈕權限,什麼意思呢?github

比方說咱們如今要開發一個頁面,叫作用戶管理,在用戶管理這個頁面會進行一些對用戶增刪查改的操做。我管這個用戶管理叫作菜單權限,它下面的增刪查改(接口)的操做叫作按鈕權限。這些接口的p_id很顯然就是這個菜單權限的主鍵ID了。typescript

[
  {
    p_id: '',
    id: 1000,
    name: '權限管理',
    type: 1,   // 菜單
    permission: 'permission_manage',
    children: [
      {
        p_id: 1000,
        id: 1100,
        name: '用戶管理',
        type: 1, // 菜單
        permission: 'user_manage',
        children: [
          {
            p_id: 110,
            id: 1101,
            name: '添加用戶',
            type: 2, // 按鈕
          }
          ...
        ]
      }
    ]
  }
]
複製代碼

怎麼樣,這樣的數據結構是否是很熟悉,是否是就是管理系統中左側菜單。這個 菜單權限,就是前端在作頁面訪問控制時所要用到的東西。這個數據結構只是我爲了方便理解這樣寫的。 在個人項目中我向後端查詢到的權限數據不長這個樣子,就是一個數組,每一項是數據,沒有作分組操做(就是沒有children)。這樣前端拿到數據了以後就能夠根據 type 去整合成菜單權限集合和按鈕權限集合,方便了後續的使用。數據庫

前端代碼去實現權限控制

理解了權限是怎麼設計的,接下來講說前端代碼怎麼去實現。redux

我過往的項目中所使用的都是 react + antd + dva + typescript。其實前端所選用的技術是什麼並不重要,重要的是思路理解了,剩下的只是代碼實現的不一樣。

首先我會要後端給我提供一個接口,查詢當前用戶的全部權限。而後我會把它分爲 菜單權限按鈕權限redux 去管理。

渲染左側菜單

首先是渲染左側菜單。在項目中通常狀況下會有一個專門的左側菜單的配置文件,在該文件裏定義了菜單的名字啊、圖標啊、頁面路徑等信息。有些菜單頁面是須要被權限管理的,而有些則不須要。對於須要被權限管理的頁面我會添加一個字段叫作菜單標識。

interface MenuDataItem {
    name: string;  // 菜單名字
    icon?: string;
    path: string;
    children?: Array<MenuDataItem>;
    permission?: string;  // 菜單標識
  }
  const menuData: MenuDataItem[] = [...];
複製代碼

項目中的左側菜單,就會根據這個 menuData 被渲染出來。這裏的邏輯是首先看這個菜單有沒有菜單標識,若是沒有的話直接渲染。若是有菜單標識的話,就看用戶是否具備這個菜單權限,有就渲染,沒有就不渲染。每一個項目的結構確定不一樣,我就很少貼代碼了,重要的是思路,具體實現我寫了demo,傳到了github上,感興趣能夠去看,這是地址:admin-permission-demo

路由層面的控制

只管理了左側菜單的渲染確定是不夠的,須要在路由層面再去作控制。通常狀況下項目中會有一份路由表,react的話路由也是組件,在路由渲染的地方去作控制就行。vue 的話是全局配置 router 的,在路由守衛中限制就行。一樣的,頁面對應菜單路由,看用戶是否具備菜單權限,不具有就到提示權限不夠頁面,具有就正常顯示頁面。

按鈕層面的控制

仍是拿用戶管理來舉一個例子,增、刪、查、改。 可能用戶只具有 刪、查、改的權限而不具有增的權限。這時候在頁面中就不該該渲染 「添加用戶」 這樣的按鈕了,否則用戶數據輸入了半天,一發請求後端一校驗提示權限不足就尷尬了,我都不能作這個操做,你還展示給我幹啥?

這時候去寫一個組件,叫啥不重要,就好比說叫 PermissionButton 把。react的話將本來按鈕做爲 children 傳入該組件,vue 的話應該就是 <slot>。而後該組件還接收一個 props,它是一個數組,就叫他 permissions 把。該數組的每一項就是按鈕權限標識,表明須要哪些權限才能展現這個按鈕,或者也有可能具備其中一項就能夠展現。在提供一個props去控制把,值爲 every 或者 some。every就是全都有才能展現,some就是具有其中一項就能展現。

而後就是去查用戶的 按鈕權限 了。 具有了改組件就展現 本來組件,不具有就不展現就好了。

總結

這是我作後臺管理系統所積累的一點實踐把。若是你們有何更好的方案,或者以爲哪裏能夠改進的歡迎交流。

對 vue 的用戶可能不太友好。由於demo是react實現的。可是我並不以爲這個方案在react和vue下有太大的差別。若是後面我在工做中有使用vue去作的機會,在更新一版使用vue的demo把。最重要的仍是要去理解這個權限,其實也是簡單的東西。但願可以幫助到有須要的人。

具體實現確定不是幾行代碼可以貼清楚的,代碼怎麼實現也關係到具體的項目結構。

我提供了demo,上傳到了github上,地址爲:admin-permission-demo

demo也是根據我本身搭的管理系統模板作的,地址爲:antd-admin

相關文章
相關標籤/搜索