【一】概論
(1)簡介
rbac(role based access controal),全稱基於用戶組/角色的權限控制。
(2)概況
目前來說,一般項目有兩種權限管理方式①傳統方式;②rbac方式。下面依次介紹下
【二】傳統模式與RBAC模式對比
(1)傳統權限分配方式
典型特征:將權限和用戶掛鈎,直接將權限綁定到用戶。例如ecs電商管理平台的人員權限分配

缺點:①效率上較低;②設置權限時沒有統一標准。所以上述權限分配方式,在大型網站不會使用
(2)RBAC權限管理方式
在使用時有兩種體現方式①基於表結構的rbac權限管理;②基於文件結構的rbac權限管理
區別:數據的存儲位置,基於表結構的數據保存在數據表(3表、5表),基於文件結構的數據保存在文件里。但原理相同
拓展:3表和5表區別,若將數據拆分到不可拆分的程度,使用5表;否則使用3表
3表包含:用戶表、用戶組表、權限表;5表就是將3表里的權限表、用戶組表進行再次拆分。
基於數據表的形式:優點在於后期數據維護上更加方便,有界面來操作數據表。
基於文件的形式:優點在於簡單容易理解,缺點是不易於維護(因為寫在了文件里,沒有維護界面。所以后期維護修改時比較困難)
(3)RBAC原理

描述:在用戶登錄的時候,會持久化用戶登錄信息(如角色id),然后根據id去查詢該角色的權限。這里的權限是用戶組權限
然后在中間控制器中去獲取當前用戶訪問的控制名和方法名,組成與預定義格式一致的形式,來判斷組成后的形式在不在權限信息當中。如果在則表示有權限,如果不在則表示沒有權限。
(4)RBAC權限分配方式
RBAC權限方式的最大特點:將權限和用戶組掛鈎,然后將用戶組和用戶進行掛鈎。

從圖中可以發現RBAC模式優點:①設計時項目前期,權限的標准就已經可以做到統一了;②維護上更加簡單快捷
一般大型網站項目里,使用RBAC模式較多
【三】案例
針對OA系統,實現RBAC權限管理
第一步:定義用戶組的權限信息數據,當前模式是基於文件的權限管理方式,所以數據需要寫在文件里。
寫在哪個文件里呢?
可以寫在配置文件或者單獨寫文件引入。這里建議寫在配置文件里,因為配置文件是系統自動加載的,所以寫在配置文件里,后期用的話不需要再進行引入了。
配置文件的話可以寫到應用級別配置文件Application\Common\Conf\config.php,或者分組級別配置文件Application\Home\Conf\config.php
這里我推薦選擇應用級別配置文件Common]Conf\config.php

之前說過3表為用戶表、用戶組表、權限表
將權限配置寫到下面即可
//RBAC權限數據 // 1. 角色數組 'RBAC_ROLES' => array( 1 => '高層管理', 2 => '中層領導', 3 => '普通職員' ), //2. 權限數組(關聯角色數組),通過數字123將角色和權限數組關聯 'RBAC_ROLE_AUTHS' => array( 1 => '*/*',//擁有全部權限(當前控制器名和方法名組成的權限),這里的/區別控制器和方法 2 => array('email/*','doc/*','knowledge/*'),//中層管理 3 => array('email/*','knowledge/*') ),
第二步:在指定地方去根據當前用戶的role_id來獲取當前用戶應當有的權限。通過用戶組id拿到相應權限,拿到權限信息后再獲取權限名和方法名.
換用旺用戶登錄,權限為3

因為要根據當前用戶的role_id去獲取判斷用戶權限,既然和翻牆一樣,也和權限掛鈎了。為了防止翻牆,寫到了中間控制器里,這里同樣也需要判斷權限,所以和翻牆寫到一起。減少代碼重復。寫到控制器CommonController.class.php里
第三步:編寫位置----中間控制器的構造方法
第四步:先測試下用戶的role_id,這里我登錄的用戶是旺,role_id為3.所以瀏覽器顯示3

關於登錄時用戶信息的持久化在登錄控制器里已經寫好了

接着因為權限信息在配置文件里,所以接下來用C方法讀取配置信息,獲取權限
//因為權限信息在配置文件里,所以接下來用C方法讀取配置信息,獲取權限 $rbac_role_auths = C('RBAC_ROLE_AUTHS');//獲取全部的用戶組的權限 dump($rbac_role_auths);die;
這里輸出打印下是否獲取到全部權限信息,瀏覽器顯示結果
array(3) {
[1] => string(3) "*/*"
[2] => array(3) {
[0] => string(7) "email/*"
[1] => string(5) "doc/*"
[2] => string(11) "knowledge/*"
}
[3] => array(2) {
[0] => string(7) "email/*"
[1] => string(11) "knowledge/*"
}
}
接下來獲取當前用戶的權限,然后輸出打印下
$currRoleAuth = $rbac_role_auths[$role_id];//獲取當前用戶對應的權限 dump($currRoleAuth);die;
瀏覽器顯示結果為
array(2) {
[0] => string(7) "email/*"
[1] => string(11) "knowledge/*"
}
此時上面已經走完了

接下來下面
第四步:通過常量的方式獲取當前用戶訪問的路由中控制器名和方法名,並且組成預定義的格式
可以理解為,在中間控制器構造方法里獲取當前訪問的控制器名和方法名,通過什么獲取呢?通過常量獲取
//通過常量的方式獲取當前用戶訪問的路由中控制器名和方法名 $controller = strtolower(CONTROLLER_NAME);//轉成和預定義的一樣,小寫 dump($controller);die;
瀏覽器輸出控制器名index
接下來獲取方法名,繼續添加
//通過常量的方式獲取當前用戶訪問的路由中控制器名和方法名 $controller = strtolower(CONTROLLER_NAME); $action = strtolower(ACTION_NAME);
第五步:判斷是否有權限
判斷依據:判斷組成的形式是否在權限數組里,若在則表示有權限,否則沒有權限
//判斷權限,先排除超級管理員的情況 if ($role_id > 1) { //當用戶不是超級管理員時進行權限判斷 if (!in_array($controller.'/'.$action,$currRoleAuth)&&!in_array($controller.'/*', $currRoleAuth)) { //用戶沒有權限 $this->error('您沒有權限');die; } }
此時刷新瀏覽器驗證下,會登錄成功,但是顯示首頁失敗,一直顯示沒有權限,然后重新登錄,然后沒有權限,然后重新登錄。。。。。在沒有權限和登錄一直循環


為什么會出現這種情況呢?
原來因為沒有在配置文件里加index控制器,所以接下來加上

現在可以進行驗證測試了,普通員工沒有職員管理的權限,所以如果點擊職員管理會提示沒有權限
如果想讓用戶在跳頁時跳轉到首頁,可以在控制器里編寫方法

【總結】
按照步驟執行

.
