PHP项目RBAC权限模型如何搭建

wen PHP项目 21

本文目录导读:

PHP项目RBAC权限模型如何搭建

  1. 数据库设计
  2. RBAC核心类实现
  3. 中间件实现
  4. 使用示例
  5. 进阶优化

我来详细介绍PHP项目中RBAC权限模型的搭建方案。

数据库设计

基础表结构

-- 用户表
CREATE TABLE `users` (
    `id` INT PRIMARY KEY AUTO_INCREMENT,
    `username` VARCHAR(50) NOT NULL,
    `password` VARCHAR(255) NOT NULL,
    `email` VARCHAR(100),
    `status` TINYINT DEFAULT 1,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 角色表
CREATE TABLE `roles` (
    `id` INT PRIMARY KEY AUTO_INCREMENT,
    `name` VARCHAR(50) NOT NULL,
    `description` VARCHAR(200),
    `status` TINYINT DEFAULT 1,
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 用户角色关联表
CREATE TABLE `user_roles` (
    `user_id` INT NOT NULL,
    `role_id` INT NOT NULL,
    PRIMARY KEY (`user_id`, `role_id`),
    FOREIGN KEY (`user_id`) REFERENCES `users`(`id`),
    FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`)
);
-- 权限表
CREATE TABLE `permissions` (
    `id` INT PRIMARY KEY AUTO_INCREMENT,
    `name` VARCHAR(50) NOT NULL,
    `code` VARCHAR(100) NOT NULL UNIQUE, -- 权限代码
    `module` VARCHAR(50), -- 所属模块
    `description` VARCHAR(200),
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 角色权限关联表
CREATE TABLE `role_permissions` (
    `role_id` INT NOT NULL,
    `permission_id` INT NOT NULL,
    PRIMARY KEY (`role_id`, `permission_id`),
    FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`),
    FOREIGN KEY (`permission_id`) REFERENCES `permissions`(`id`)
);

RBAC核心类实现

PermissionManager.php

<?php
class PermissionManager {
    private $db;
    public function __construct($db) {
        $this->db = $db;
    }
    /**
     * 获取用户所有权限
     */
    public function getUserPermissions($userId) {
        $sql = "SELECT DISTINCT p.code, p.name, p.module
                FROM permissions p
                JOIN role_permissions rp ON p.id = rp.permission_id
                JOIN user_roles ur ON rp.role_id = ur.role_id
                WHERE ur.user_id = :user_id";
        $stmt = $this->db->prepare($sql);
        $stmt->execute(['user_id' => $userId]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    /**
     * 检查用户是否有指定权限
     */
    public function checkPermission($userId, $permissionCode) {
        $sql = "SELECT COUNT(*) as count
                FROM user_roles ur
                JOIN role_permissions rp ON ur.role_id = rp.role_id
                JOIN permissions p ON rp.permission_id = p.id
                WHERE ur.user_id = :user_id 
                AND p.code = :permission_code";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([
            'user_id' => $userId,
            'permission_code' => $permissionCode
        ]);
        return $stmt->fetch(PDO::FETCH_ASSOC)['count'] > 0;
    }
    /**
     * 检查用户是否有多个权限(且关系)
     */
    public function checkAllPermissions($userId, array $permissionCodes) {
        $placeholders = implode(',', array_fill(0, count($permissionCodes), '?'));
        $sql = "SELECT DISTINCT p.code
                FROM user_roles ur
                JOIN role_permissions rp ON ur.role_id = rp.role_id
                JOIN permissions p ON rp.permission_id = p.id
                WHERE ur.user_id = ?
                AND p.code IN ($placeholders)";
        $stmt = $this->db->prepare($sql);
        $params = array_merge([$userId], $permissionCodes);
        $stmt->execute($params);
        $userPermissions = $stmt->fetchAll(PDO::FETCH_COLUMN);
        return count(array_intersect($permissionCodes, $userPermissions)) == count($permissionCodes);
    }
}

RoleManager.php

<?php
class RoleManager {
    private $db;
    public function __construct($db) {
        $this->db = $db;
    }
    /**
     * 为用户分配角色
     */
    public function assignRole($userId, $roleId) {
        $sql = "INSERT IGNORE INTO user_roles (user_id, role_id) 
                VALUES (:user_id, :role_id)";
        $stmt = $this->db->prepare($sql);
        return $stmt->execute([
            'user_id' => $userId,
            'role_id' => $roleId
        ]);
    }
    /**
     * 移除用户角色
     */
    public function removeRole($userId, $roleId) {
        $sql = "DELETE FROM user_roles 
                WHERE user_id = :user_id AND role_id = :role_id";
        $stmt = $this->db->prepare($sql);
        return $stmt->execute([
            'user_id' => $userId,
            'role_id' => $roleId
        ]);
    }
    /**
     * 获取用户所有角色
     */
    public function getUserRoles($userId) {
        $sql = "SELECT r.* FROM roles r
                JOIN user_roles ur ON r.id = ur.role_id
                WHERE ur.user_id = :user_id";
        $stmt = $this->db->prepare($sql);
        $stmt->execute(['user_id' => $userId]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    /**
     * 为角色分配权限
     */
    public function assignPermission($roleId, $permissionId) {
        $sql = "INSERT IGNORE INTO role_permissions (role_id, permission_id) 
                VALUES (:role_id, :permission_id)";
        $stmt = $this->db->prepare($sql);
        return $stmt->execute([
            'role_id' => $roleId,
            'permission_id' => $permissionId
        ]);
    }
}

中间件实现

AuthMiddleware.php

<?php
class AuthMiddleware {
    private $permissionManager;
    private $session;
    public function __construct($permissionManager, $session) {
        $this->permissionManager = $permissionManager;
        $this->session = $session;
    }
    /**
     * 检查是否登录
     */
    public function requireLogin() {
        if (!$this->session->has('user_id')) {
            header('Location: /login');
            exit;
        }
    }
    /**
     * 检查权限
     */
    public function requirePermission($permissionCode) {
        $this->requireLogin();
        $userId = $this->session->get('user_id');
        if (!$this->permissionManager->checkPermission($userId, $permissionCode)) {
            // 返回403禁止访问
            http_response_code(403);
            echo json_encode(['error' => 'Access denied']);
            exit;
        }
    }
}

使用示例

权限检查与路由

<?php
// 初始化
$db = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$permissionManager = new PermissionManager($db);
$authMiddleware = new AuthMiddleware($permissionManager, $_SESSION);
// 路由示例
class UserController {
    // 需要登录才能访问
    public function profile() {
        global $authMiddleware;
        $authMiddleware->requireLogin();
        // 显示用户信息
    }
    // 需要特定权限
    public function deleteUser($userId) {
        global $authMiddleware;
        $authMiddleware->requirePermission('user.delete');
        // 执行删除操作
    }
    // 需要多个权限
    public function adminPanel() {
        global $authMiddleware;
        $authMiddleware->requirePermission('admin.access');
        // 管理员面板
    }
}
// 缓存用户权限
class UserPermissionCache {
    private $cache = [];
    public function getUserPermissions($userId) {
        if (!isset($this->cache[$userId])) {
            $this->cache[$userId] = $this->loadPermissions($userId);
        }
        return $this->cache[$userId];
    }
}

进阶优化

缓存优化

<?php
class PermissionCache {
    private $redis;
    private $ttl = 3600; // 1小时缓存
    public function getCachedPermissions($userId) {
        $key = "user_permissions:{$userId}";
        $cached = $this->redis->get($key);
        if ($cached) {
            return json_decode($cached, true);
        }
        $permissions = $this->loadFromDatabase($userId);
        $this->redis->setex($key, $this->ttl, json_encode($permissions));
        return $permissions;
    }
    public function clearUserCache($userId) {
        $this->redis->del("user_permissions:{$userId}");
    }
}

树形权限结构

<?php
class TreePermissionManager extends PermissionManager {
    public function getPermissionTree() {
        $sql = "SELECT id, name, code, parent_id 
                FROM permissions 
                ORDER BY parent_id, sort_order";
        $permissions = $this->db->query($sql)->fetchAll(PDO::FETCH_ASSOC);
        return $this->buildTree($permissions);
    }
    private function buildTree(array $items, $parentId = null) {
        $tree = [];
        foreach ($items as $item) {
            if ($item['parent_id'] === $parentId) {
                $children = $this->buildTree($items, $item['id']);
                if ($children) {
                    $item['children'] = $children;
                }
                $tree[] = $item;
            }
        }
        return $tree;
    }
}

这个RBAC权限模型提供了完整的权限管理解决方案,包括数据库设计、核心类实现、中间件集成和缓存优化等关键功能,你可以根据具体项目需求进行调整和扩展。

抱歉,评论功能暂时关闭!