天天看點

資料權限系統

在之前寫過一篇關于菜單權限系統的設計,是以為了完善整個權限系統的模型,決定把資料權限也做一個總結。菜單權限管理系統

目标

實作對資料的權限控制。簡單的來說,就是決定誰可以操作(增删改查)哪些資料。

該權限模型的适用範圍

該模型目前在一些常用的管理平台得到的驗證與實施,目前已應用在多個公司産品中,主要場景是CRM類項目。

核心難點

資料權限的主要難度在于查詢的性能、授權、鑒權,字段級别的控制。

比如在百萬級别規模時,mysql如何實作秒級别的查詢?

場景介紹:在之前設計該權限模型時,我們的項目遇到了一個核心的難題,sql的查詢速度非常的緩慢!!!一個sql可能高達10S+。這對于使用者而言,是無法接受的。是以我們嘗試去優化sql的表設計,索引的優化,但是最終結果都擺陣下來。主要的問題是我們并沒有足夠抽象資料,導緻百萬級别的資料下,sql非常緩慢。這裡面占時不需要考慮分庫分表(百萬級别的規模不足以使用該手段)。

百萬級别的資料權限怎麼授予使用者?

場景介紹:面對如此大的資料量,如何授權使用者權限呢?總不能是逐個配置設定的!!!

如何快速高效的進行資料鑒權呢?

場景介紹:這麼大的資料量,在程式中不容易處理,必須借助于資料庫的高效查詢方案,但是怎麼實作呢?

如何實作字段級别的權限控制?

場景介紹:字段級别的權限怎麼控制?控制sql的生成邏輯?還是怎麼處理呢?

權限模型的抽象

有了那麼多的問題,我們先從權限模型入手,我們必須高度抽象化我們的權限系統,才有機會做到。

下面我們直接貼出一個圖,介紹該模型的一些核心概念

資料權限系統

我們根據上圖所示,可以觀察到下面的幾個元素,分别是:權限實體,部門,角色,菜單權限。

其中菜單權限參考上面的連結

權限實體:這個是該權限模型的核心元素,也就是我們需要系統控制的資料。比如客戶,訂單,管道,區域等。

部門:這個簡單,就是一般的部門組織結構

角色:抽象的實體,用于快速配置設定權限相同權限給一批使用者,與菜單權限的角色概念一緻。

權限的查詢模型

在上面的圖中,不知道大家是否看到了一條sql

select xxx from xx_table where account in (xxx) and product_group in (xxx) and country in (xxx)
           

沒錯,這就是該模型的查詢模型。其中account,product_group,country代表需要做權限控制的權限實體。

在這裡面隻是一個簡單的模型,如果account或者country等資料量足夠大時,我們會發現mysql in查詢是會出現非常嚴重的查詢性能的。比如account資料量規模為100W時...

引入部門組織結構,突破資料量的限制

還是看上圖,我們有一個部門組織結構,我們可以想象下,比如總經理,自然是可以檢視所有部門的資料。假設A部門經理,可以檢視A部門以及子部門的資料。如果是普通的員工,隻能檢視自己賬号下的資料。

下面我們給出一個部門組織結構圖,并且給每個部分标志一個key,key的生成規則如下

1.根部門的key為數字10

2.根部門的直屬部門的key為10 001,10 002,10 003...以此類推

3.其他的key生成邏輯和步驟2相同,唯一不同的就是key的長度變長了,比如:10 001 001,10 001 002

這裡面我們給部門打上如下的key,為了友善介紹,我們還是貼圖檔

資料權限系統

有了該模型,我們結合mysql的前置查詢索引的特性(org like 'xxxx%')

where org like '10%'
           
org like '10001%'
           
org like '10002%'
           

上面的查詢,在mysql下,200W的資料規模,可以實作1S内響應!!!

如何授權

解決了查詢的性能,其實授權也就很簡單了。

授權我們一般根據員工的崗位來設定,普通員工,部門經理

普通員工:不需要單獨授權,直接綁定員工工号即可

部門經理:設定該員工可以檢視的部門(支援多個)

如何鑒權

鑒權和授權一般是互相的一個過程

1.判斷該員工是否為部門經理

2.如果是,取出部門的key

3.添加到sql中,使用mysql前置like查詢資料

字段權限的控制

字段權限的控制,我們直接針對接口程式設計,不要針對sql程式設計。

比如擷取員工清單:我們隻需要控制輸出的字段屬性即可。

為啥不針對sql程式設計?因為sql需要考慮各種join,字段是否缺失,關聯的内容存儲在其他表等情況

資料庫的實作

1.識别權限實體

2.給權限實體加上一個工号字段,一個部門字段,比如:emp_id,org_key

3.查詢時,先擷取員工的角色權限,如果是部門經理,那麼擷取對應的key清單

4.建構sql,加入部門或者工号的sql片段

  • org_key lik '10 001%' or org_key like '10 002%',這是部門的sql
  • emp_id = 'xxx',這是普通員工的sql

總結

設計好一個權限系統,說難不難,但是也不簡單。

主要的難點在于

1.識别出你需要控制的資料(權限實體)

2.高效的查詢效率與sql的索引相結合(這裡面使用部門key與sql的前置查詢)

應用于擴充

該模型設計簡單,具備一定的普遍性,是以在設計時,我們可以根據不同的系統去進行演進與擴充。大家有興趣的可以思考下

繼續閱讀