phpcms中的RBAC權限系統

PHPCMS中的RBAC權限系統主要用到了4張數據表:管理員表,角色表,菜單表,菜單權限表。先來看看數據庫的數據表結構:php

admin 管理員表

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 email varchar(40) YES Email
9 realname varchar(50) NO 真實姓名
10 card varchar(255) NO 密保卡

admin_role 角色表

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 顯示

admin_role_priv 菜單權限表

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 所屬站點

下面來簡單分析一下4張表的關係:

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()數組

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 模板中調用的,主要進行的操做是先取出菜單表中全部菜單,而後判斷當前角色,若是爲超級管理員,則直接返回菜單數組,反之,則將符合當前角色權限的菜單數組返回。加密

以上就是PHPCMS系統的權限結構及操做流程!code

相關文章
相關標籤/搜索