RBAC(Role-Based Access Control,基於角色的存取控制)是企業級應用權限管理的主流方案。ThinkPHP 內建 Rbac.class.php 提供開箱即用的實現。本文從核心方法、資料表設計、登入驗證流程三個維度深度解析,助你快速掌握 TP RBAC 精髓。
| 表名 | 用途 | 關鍵欄位 |
|---|---|---|
| role | 角色表 | id, name, remark, status |
| role_user | 用戶-角色關聯 | role_id, user_id |
| node | 節點表(權限點) | id, name, title, pid, level, module |
| access | 權限表 | role_id, node_id, level, module |
關係說明: 用戶 ↔ 角色(多對多),角色 ↔ 節點(多對多),節點對應具體模組/控制器/方法。
位於 Lib/Org/Util/Rbac.class.php
$_SESSION['_ACCESS_LIST']。$_SESSION[C('ADMIN_AUTH_KEY')])C('USER_AUTH_ON') 且 C('AUTH_TYPE')=2),每次請求重新查庫。判斷當前訪問的模組/控制器/方法是否在「無需認證清單」(NOT_AUTH_MODULE)中,內部自動調用,開發者無需關心。
檢查 $_SESSION[C('USER_AUTH_KEY')] 是否存在,未登入則跳轉至 C('LOGIN_URL')。
流程圖:
1. checkAccess() → 需認證?
├─ 否 → 放行
└─ 是 → 是超級管理員?
├─ 是 → 放行
└─ 否 → 即時認證?
├─ 是 → 重新 getAccessList() 查庫判斷
└─ 否 → 從 $_SESSION['_ACCESS_LIST'] 讀取判斷
執行多表關聯 SQL,支援角色繼承(role.pid),但作者建議「放棄繼承功能,改用扁平化角色設計,擴展性更強」。
public function login() {
// ... 驗證帳密 ...
$_SESSION[C('USER_AUTH_KEY')] = $user['id']; // 必須存 uid
if ($user['is_admin']) {
$_SESSION[C('ADMIN_AUTH_KEY')] = true;
}
Rbac::saveAccessList(); // 寫入快取
}
class BaseController extends Controller {
protected function _initialize() {
// 1. 檢查登入
if (!Rbac::checkLogin()) redirect(U('Public/login'));
// 2. 檢查權限
if (!Rbac::AccessDecision()) {
if (IS_AJAX) $this->error('無權限操作');
else $this->error('無權限訪問');
}
}
}
Rbac.class.php 全文,理解 SQL 拼裝與快取策略。BuildRbac 行為擴展,自動同步節點表,避免手動維護。_ACCESS_LIST,並提供「清除權限快取」後台按鈕。ThinkPHP RBAC 以「約定優於配置」降低接入門檻,核心在於 saveAccessList 快取與 AccessDecision 判斷雙引擎。掌握資料表關係、例外機制、即時/快取兩種模式,即可靈活應對大多數業務場景。