php 实现 rbac
实现 RBAC 的基本步骤
定义角色和权限表结构
创建数据库表存储角色、权限及关联关系。通常需要以下表:
roles(角色表):包含角色ID、名称等字段。permissions(权限表):包含权限ID、名称、标识符(如user.create)。role_permission(角色-权限关联表):存储角色与权限的多对多关系。user_role(用户-角色关联表):存储用户与角色的多对多关系。
示例 SQL 结构:

CREATE TABLE roles (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) UNIQUE
);
CREATE TABLE permissions (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
slug VARCHAR(50) UNIQUE
);
CREATE TABLE role_permission (
role_id INT,
permission_id INT,
PRIMARY KEY (role_id, permission_id),
FOREIGN KEY (role_id) REFERENCES roles(id),
FOREIGN KEY (permission_id) REFERENCES permissions(id)
);
CREATE TABLE user_role (
user_id INT,
role_id INT,
PRIMARY KEY (user_id, role_id),
FOREIGN KEY (role_id) REFERENCES roles(id)
);
核心功能实现
权限检查逻辑
通过用户ID查询其角色关联的权限,判断是否拥有特定权限。示例 PHP 代码:
function hasPermission($userId, $permissionSlug) {
$sql = "SELECT p.slug
FROM permissions p
JOIN role_permission rp ON p.id = rp.permission_id
JOIN user_role ur ON rp.role_id = ur.role_id
WHERE ur.user_id = ? AND p.slug = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$userId, $permissionSlug]);
return $stmt->fetch() !== false;
}
中间件实现
在路由或控制器前拦截请求,验证权限:

class PermissionMiddleware {
public function handle($request, $permission) {
if (!hasPermission($_SESSION['user_id'], $permission)) {
header('HTTP/1.0 403 Forbidden');
exit('Access denied');
}
}
}
// 使用示例
$middleware = new PermissionMiddleware();
$middleware->handle($request, 'post.delete');
扩展优化
缓存权限数据
频繁查询数据库可能影响性能,可缓存用户权限到 Redis 或 Session:
function loadUserPermissions($userId) {
$cacheKey = "user_permissions_{$userId}";
if ($cached = cache_get($cacheKey)) {
return $cached;
}
$permissions = queryPermissionsFromDB($userId);
cache_set($cacheKey, $permissions, 3600);
return $permissions;
}
动态权限管理
提供后台界面管理角色和权限,允许管理员动态分配权限:
// 添加权限到角色
function assignPermissionToRole($roleId, $permissionId) {
$sql = "INSERT INTO role_permission (role_id, permission_id) VALUES (?, ?)";
$pdo->prepare($sql)->execute([$roleId, $permissionId]);
}
安全注意事项
- 最小权限原则:默认拒绝所有权限,仅显式分配必要权限。
- 输入过滤:检查用户输入防止 SQL 注入(如使用 PDO 预处理语句)。
- 定期审计:定期检查权限分配是否合理,避免权限泄露。
通过以上步骤,可构建一个灵活且安全的 RBAC 系统。






