我已經嘗試了很多關於權限的不同的方案,我已經永遠只找到了一個方法,使他們的工作滿足程序員和客戶端在幾乎所有情況下。這是爲了讓他們部分受數據驅動。
我最近的一個嘗試是這樣的:
- 每個用戶連接到它的權限對象。在我的情況下,當用戶被請求時自動創建。 (在我的情況下,權限可以針對不同部分的不同,所以用戶可能被允許用於Y做X而不是Z.)
- 每個頁面,需要被寬容的代碼塊,或視圖是包裹着一個如果語句檢查權限對象。如果該權限也需要擔心該部分,則將當前相關的部分ID作爲數組傳遞,返回一組新的布爾值以進行匹配。
- 接口然後不直接向用戶暴露這個複雜的混亂,而是一個superadmin接口允許創建新的用戶類型。這些類型攜帶將爲該'類型'的用戶啓用的權限集。不同類型的權限可能會有重疊,因此管理員和編輯者都可以「編輯複製」或其他內容。
- 正常的管理界面讓個人用戶可以設置爲不同部分的不同用戶類型。因此,一個用戶可能是第2部分的管理員,第2,第3,第4和第5部分的編輯者。它們也可以在全局範圍內設置,從而重載未使用的部分(0)。
這有很多好處,一個缺點。首先,缺點。因爲這些密鑰直接放入代碼中,所以只有superadmin(又名開發人員)才能訪問該部分接口。實際上,根本不需要接口,因爲權限列表只應隨代碼而改變。真正的問題在於,在運行代碼之前,您不會知道標題有什麼問題,因爲語法會很好。現在,如果這是用C#編寫的,這將是一個非常嚴重的問題。但幾乎所有的PHP都不是安全的,所以它對於課程來說確實是不合格的。這些值也可以從配置文件中加載,甚至可以從您構建用戶類型的GUI中加載,儘管這似乎是錯誤的。
您從此獲得什麼能力,建立新的權限類型的飛行。您可以相對容易地重命名這些權限。 (由於系統只使用數字,因此標題僅用於捕獲數字,因此可以在幾個地方輕鬆更改)。代碼使用起來非常簡單。這將是這個樣子:
if($current_user->permissions->can("View Sales Records"))
{
//Code to view sales records
}
或者稍微複雜
$sections = array(1,2,3,4); //Probably really a list of all sections in the system
$section_permissions = $current_user->permissions->these($sections)->can("Edit Section");
foreach($sections as $s)
{
if($section_permissions[$s])
{
// Code for maybe displaying a list of sections to edit or something
}
}
的方法鏈接很簡單了。 ->these()
將內部數組設置爲這些值,然後返回對該對象本身的引用。 ->can()
然後作用於該列表,如果它存在,然後取消它。在我自己的版本中,我也有->any()
它總是返回一個完整的部分列表,所以我可以檢查->any()->can()
。
最後,許可對象還包含一個用戶是什麼類型的列表。這使得顯示用戶列表和激活的權限變得非常簡單。在我的情況下,我們只需使用->types()
來訪問該列表中的一個數組ids => names
。
不存在的權限標題被忽略。它們還以小寫字母和空格和特殊字符進行匹配,以幫助減少輸入錯誤帶來的問題。我考慮過甚至在進行levenshtein距離檢查並選擇最接近的比賽。但最終最好不要依賴這樣的事情。 (可能會記錄錯誤,但優雅地選擇最接近的匹配。)
在代碼和界面之外,用戶只需要在一個So-in-so中相互關聯即可,這是一個Admin,Editor,Publisher ,作家,首席執行官等等。爲不同的組織創建不同組的用戶類型也是微不足道的。
的這一切部件可以大量緩存,建立一個基本的用戶在所有還沒有登錄誰的人是很容易的,我還沒有遇到那個不明顯一個基於權限的問題用這個結構來解決。
我只希望我可以與你分享實際的代碼。我自己並不擁有它,因此不能發佈它。
我也很想找到這個答案。我們正在使用派對模型,並考慮使用自己的斷言在應用程序中扮演'客戶'的角色(在Zend ACL中說),但它看起來很笨重。 – boatingcow