原文連接:http://www.javashuo.com/article/p-houkdpke-ga.htmlphp
PHPCMS中的RBAC權限系統主要用到了4張數據表:管理員表,角色表,菜單表,菜單權限表。先來看看數據庫的數據表結構:html
ID | 字段 | 類型 | Null | 默認 | 索引 | 額外 | 註釋 |
---|---|---|---|---|---|---|---|
1 | userid | mediumint(6) | unsigned | PK | auto_increment | 用戶id | |
2 | username | varchar(20) | YES | INDEX | 用戶名 | ||
3 | password | varchar(32) | YES | 密碼 | |||
4 | roleid | smallint(5) | YES | 0 | 角色 | ||
5 | encrypt | varchar(6) | YES | 加密因子 | |||
6 | lastloginip | varchar(15) | YES | 最後登陸ip | |||
7 | lastlogintime | int(10) unsigned | YES | 0 | 最後登陸時間 | ||
8 | varchar(40) | YES | |||||
9 | realname | varchar(50) | NO | 真實姓名 | |||
10 | card | varchar(255) | NO | 密保卡 |
ID | 字段 | 類型 | Null | 默認 | 索引 | 額外 | 註釋 |
---|---|---|---|---|---|---|---|
1 | roleid | tinyint(3) unsigned | PK | auto_increment | 角色id | ||
2 | rolename | varchar(50) | NO | 角色名稱 | |||
3 | description | text | NO | 描述 | |||
4 | listorder | smallint(5) unsigned | NO | 0 | INDEX | 排序 | |
5 | disabled | tinyint(1) unsigned | NO | 0 | INDEX | 狀態:1,禁用 |
ID | 字段 | 類型 | Null | 默認 | 索引 | 額外 | 註釋 |
---|---|---|---|---|---|---|---|
1 | id | smallint(6) unsigned | PK | auto_increment | 菜單id | ||
2 | name | char(40) | NO | 名稱 | |||
3 | parentid | smallint(6) | NO | 0 | INDEX | 父id | |
4 | m | char(20) | NO | INDEX | m | ||
5 | c | char(20) | NO | INDEX | c | ||
6 | a | char(20) | NO | INDEX | a | ||
7 | data | char(100) | NO | 附件參數 | |||
8 | listorder | smallint(6) unsigned | NO | 0 | INDEX | 排序 | |
9 | display | enum('1','0') | NO | 1 | 是否顯示,1 顯示 |
ID | 字段 | 類型 | Null | 默認 | 索引 | 額外 | 註釋 |
---|---|---|---|---|---|---|---|
1 | roleid | tinyint(3) unsigned | 0 | PK | 角色id | ||
2 | m | char(20) | NO | INDEX | m | ||
3 | c | char(20) | NO | INDEX | c | ||
4 | a | char(20) | NO | INDEX | a | ||
5 | data | char(30) | NO | 附件屬性 | |||
6 | siteid | smallint(5) unsigned | NO | 0 | INDEX | 所屬站點 |
1.用戶表中的每一個用戶有一個角色字段roleid,代表了該用戶屬於哪一個角色。
2.角色表的主鍵爲roleid,與用戶表中的roleid相對應,還有角色名稱,描述等,好比PHPCMS系統默認有超級管理員、總編、發佈人員等角色。
3.管理員權限表中主鍵也是roleid,與角色表中的主鍵roleid相對應,代表了該角色擁有的後臺操做權限。字段m、c、a分別表明的是模型 | 控制器 | 方法,由於PHPCMS自己也是MVC結構,因此更好地使權限系統的粒度細化到方法上面。
4.菜單表主要存放菜單屬性,其中的m、c、a與管理員權限表中的字段相對應。ajax
首先,用戶在後臺登陸,若是登陸成功,將roleid(角色id)存入SESSION,而後跳轉到後臺首頁,在PHPCMS系統中,整個後臺操做的部分都在admin模塊中,因此該模塊中全部的控制器均繼承自admin類,而且在構造方法中執行了父類的構造方法(admin的構造方法)。那麼,admin類的構造方法有執行了哪些操做呢?數據庫
首先是調用自身的 check_admin()
來判斷用戶是否登陸,緊接着判斷用戶的權限: check_priv()
數組
## 格式略微修改 final public function check_priv() { if (ROUTE_M == 'admin' && ROUTE_C == 'index' && in_array(ROUTE_A, array('login', 'init', 'public_card'))) { return true; } if ($_SESSION['roleid'] == 1) { return true; } $siteid = param::get_cookie('siteid'); $action = ROUTE_A; $privdb = pc_base::load_model('admin_role_priv_model'); if (preg_match('/^public_/', ROUTE_A)) { return true; } if (preg_match('/^ajax_([a-z]+)_/', ROUTE_A, $_match)) { $action = $_match[1]; } $r = $privdb->get_one( array( 'm' => ROUTE_M, 'c' => ROUTE_C, 'a' => $action, 'roleid' => $_SESSION['roleid'], 'siteid' => $siteid ) ); if (!$r) { showmessage('您沒有權限操做該項', 'blank'); } }
該方法首先判斷當前正在進行的操做,若是是登陸或者初始化操做,則退出。
而後判斷角色是否爲超級管理員(超級管理員默認爲最高權限),若是是,依舊退出,或者若是當前方法爲公開的(沒有權限限制),一樣退出。
最後加載 admin_role_priv_model,也就是管理員權限模型,獲取當前要操做的模型 | 控制器 | 方法,利用 admin_role_priv_model 提供的方法進行查詢,若是能夠返回數據,則說明角色能夠進行當前操做,反之,彈出提示信息:您沒有權限操做該項,而後退出!cookie
對了,忘了介紹後臺菜單的生成過程啦!其實用到的仍是admin類自身的方法:admin_menu(): 不過該方法是在 index.tpl.php 模板中調用的,主要進行的操做是先取出菜單表中全部菜單,而後判斷當前角色,若是爲超級管理員,則直接返回菜單數組,反之,則將符合當前角色權限的菜單數組返回。加密