實現資料許可權控制的一種方法

2021-08-17 05:10:26 字數 2359 閱讀 5944

在企業管理系統中,常常有這樣的要求: 

1. 使用者一般只能檢視自己部門的資料 

2. 可以設定使用者可以檢視哪些部門的資料 

這種許可權的控制,一般稱為資料許可權,與之對應的功能許可權,則是系統中哪些功能可以使用——①選單、按鈕等元素能正常顯示;②如果使用者訪問了本身不可見的功能,系統也能阻止(訪問控制)。

開發時間長了,就發現程式設計一般就是兩個問題: 

1. 在**設定(資料從**來) 

2. 在**使用(資料到**去) 

比如工作流引擎,設定,即在介面上拖畫流程圖,並儲存為特定的xml資料;使用,即流程引擎解讀xml資料,使其正確的按照使用者的意圖執行程式。 

資料許可權的問題,同樣可以分成這兩個問題來處理。

設定的問題: 

在使用者設定介面,設定使用者的管轄許可權

做到這樣的設定介面,並不困難。

在這裡,主要要解決的乙個問題是,如何把這種關係儲存下來 

常規方案:使用關聯表[使用者id,組織id] 

可是發現,一旦組織機構數量多了以後(如省市縣鄉,一般乙個省就有1000個鄉/街道以上),再加上使用者數量多了以後——往往是組織機構節點越多,則使用者也越多。理論上,這個關聯表的資料量將到達千萬級(僅理論上,因為對於絕大多數使用者來說,僅能訪問本部門資料)。

創新方案:組織機構使用code做主鍵,並且在使用者表中新建欄位為「已授權的組織(authorized_orgs)」,直接使用字串逗號分隔的方式將該關係存起來。 

可是馬上會發現,這個欄位會很長很長,乙個4級的組織,一般需要8位長的**,如果選中的全部資料,按1000個單位來算,就會有9000長度(含逗號)的字串。 

這裡有乙個取巧的辦法,對於全選了資料,只儲存上級單位的code,下級單位就不儲存了——因為選中了上級就必然下級全部選上了。

該辦法要求上下級**存在一種明顯的關係,如上級**為 0100,下級**0101。 

這個取巧的辦法,理論上依然不能規避很長的組織機構**(如選的全部是葉子節點資料),但在實踐中,卻是很好的辦法——應該很少出現全部只選葉子節點,而不選父級節點的。 

使用ztree(js的樹)的**,可以這樣寫

if(ztree==null

)

var nodes =ztree.getnodes();

var arr =;

for(var i=0; i)

console.log(arr.join(","));

obj.authorizedorgs = arr.join(",");

function

pushtoarray(arr, node)

if(node.check_child_state==2||node.check_child_state==-1)

else

if(node.check_child_state==1) } }

-----分割線:以上解決怎麼設定的問題,以下討論怎麼解決使用的問題--------

資料許可權控制的基本思路,一般是會執行的sql語句中新增where條件,以便限定查出的資料, 

如 where 所屬機構 in (使用者可訪問的機構) 

而不是在資料查詢出來之後,再到**中進行過濾——因為一般都會對資料進行高效分頁,如果已經查詢出來資料,再在**中進行過濾的話,就可能出現一頁資料不足一頁的情況,資料總數也會與實際頁面上查出的資料行不一致。

第一步,在需要進行過濾的表中,要新增乙個字段,如org_code,標明每條記錄所屬的組織機構。 

第二步,在查詢語句中加入過濾條件。 

我們要加入的sql語句,大概如下: 

where 所屬機構 in ('zz0101', 'zz0102',...) 

假如我們前面存的**是'zz0100,zz0201',其中存的是其父級節點'zz0100',代表了 'zz0101', 'zz0102', ... 

所以要寫成 

where ((所屬機構 like 'zz01%') or (所屬機構='zz0201')) 

拼湊這樣的sql語句估計也是比較麻煩的一件事,有沒有簡便一點的方法呢?答案是有。 

經查,oracle,sqlserver,mysql都是支援正則式查詢的。 

這樣,我們可以把'zz0100,zz0201'變成乙個正則式,放入條件中進行查詢即可! 

變成正則式就是 '(^zz01.*)|(^zz0201)',在mysql使用正則式查詢,就是 where 所屬機構 rlike '(^zz01.*)|(^zz0201)' 

變成正則式之後,也便於放入session中進行儲存。 

什麼,你的資料庫支援正則式,orm不支援正則式,那還用orm做什麼?

Python實現 打家劫舍 的一種方法

你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警 給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額 example 1...

Pyhthon實現 Nim遊戲 的一種方法

你正在和你的朋友,一共兩人在玩nim遊戲 桌上有乙個石碓,每一次只能移除1 3個石頭。移除最後乙個石頭的為贏家。你是遊戲開始之後第乙個移動石頭的人。你和你的朋友都是很聰明的人,每一次都會選擇最優的策略。寫乙個函式判斷在給定石頭個數的前提下你能否贏得比賽 example input 4output f...

Python實現 找不同 的一種方法

給定兩個字串s和t,它們只包含小寫字母。字串t由字串s隨機重排,然後在隨機位置新增乙個字母。請找出在t中被新增的字母 example input s abcd t abcde output eexplanation e is the letter that was added.def findthe...