首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 實現簡易 ACL 權限控制(資源-角色-用戶模型)

     編輯:PHP 綜合知識

資料庫設計

-- 資源表
CREATE TABLE aclresources (
    rsid VARCHAR(64) PRIMARY KEY,
    access INT(4) DEFAULT 0, -- 0:無人 1:所有人 2:有角色 3:無角色 4:指定角色
    `desc` VARCHAR(240),
    created_at INT(10), updated_at INT(10)
) CHARSET=utf8;

-- 角色表
CREATE TABLE aclroles (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    rolename VARCHAR(32) UNIQUE,
    `desc` VARCHAR(240),
    created_at INT(10), updated_at INT(10)
) CHARSET=utf8;

-- 資源-角色關聯
CREATE TABLE ref_aclresources_aclroles (
    rsid VARCHAR(64),
    role_id INT UNSIGNED,
    PRIMARY KEY (rsid, role_id)
) CHARSET=utf8;

-- 用戶-角色關聯
CREATE TABLE ref_users_aclroles (
    user_id INT UNSIGNED,
    role_id INT UNSIGNED,
    PRIMARY KEY (user_id, role_id)
) CHARSET=utf8;

-- 用戶表
CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    email VARCHAR(128) UNIQUE,
    password VARCHAR(64),
    nickname VARCHAR(32),
    roles VARCHAR(240), -- 可冗餘儲存角色 ID 字串
    created_at INT(10), updated_at INT(10)
) CHARSET=utf8;

核心類:AclBase

class AclBase {
    const NOBODY = 0;
    const EVERYONE = 1;
    const HAS_ROLE = 2;
    const NO_ROLE = 3;
    const ALLOCATE_ROLES = 4;

    public $tbResources = 'aclresources';
    public $tbRoles = 'aclroles';
    public $tbRefResourcesRoles = 'ref_aclresources_aclroles';
    public $tbRefUsersRoles = 'ref_users_aclroles';

    // 建立/修改/刪除資源、角色、關聯等 CRUD 方法略...
    // 重點:allocateRolesForResource, allocateResourcesForRole, allocateRolesForUser
}

權限驗證核心邏輯

function aclVerify($rsid, $user = null) {
    if (empty($rsid)) return false;
    $rs = aclGetResource($rsid); // 從快取/DB 取得資源定義
    if (!$rs) return false; // 未定義資源預設拒絕

    $access = AclBase::formatAccessValue($rs['access']);

    // 1. 全域規則
    if ($access == AclBase::EVERYONE) return true;
    if ($access == AclBase::NOBODY) return false;

    // 2. 取得當前用戶角色
    if (empty($user)) $user = $_SESSION['SI-SysUser'] ?? null;
    if (empty($user)) return false;
    $userRoles = empty($user['roles']) ? [] : explode(';', $user['roles']);
    $hasRoles = !empty($userRoles);

    // 3. 角色存在性規則
    if ($access == AclBase::NO_ROLE) return !$hasRoles;
    if ($access == AclBase::HAS_ROLE) return $hasRoles;

    // 4. 指定角色規則:檢查用戶角色與資源允許角色的交集
    if ($access == AclBase::ALLOCATE_ROLES) {
        foreach ($userRoles as $rid) {
            if (aclGetRefResourcesRoles($rsid, $rid)) return true;
        }
    }
    return false;
}

快取機制

將三張核心表載入記憶體/檔案快取(aclGetACT、aclRebuildACT),驗證時直接查快取,避免每請求查資料庫。

適用場景

  • 中型專案需細粒度權限控制(模組、功能、按鈕級)。
  • 角色、資源動態變更頻率較低,適合快取。
  • 可擴充支援「權限繼承」、「臨時授權」等進階功能。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved