本文目录导读:

我来为您详细介绍PHP项目中的代理与访问控制机制。
代理模式实现
简单代理类
<?php
// 代理接口
interface Subject {
public function request($data);
}
// 真实主题类
class RealSubject implements Subject {
public function request($data) {
return "处理数据: " . $data;
}
}
// 代理类
class Proxy implements Subject {
private $realSubject;
private $accessControl;
public function __construct() {
$this->realSubject = new RealSubject();
$this->accessControl = new AccessControl();
}
public function request($data) {
// 前置处理
if (!$this->accessControl->checkPermission()) {
throw new Exception("无权访问");
}
// 记录日志
$this->logRequest($data);
// 调用真实对象
$result = $this->realSubject->request($data);
// 后置处理
$this->cacheResult($data, $result);
return $result;
}
private function logRequest($data) {
// 记录请求日志
}
private function cacheResult($key, $value) {
// 缓存结果
}
}
// 使用
$proxy = new Proxy();
try {
echo $proxy->request("测试数据");
} catch (Exception $e) {
echo "错误: " . $e->getMessage();
}
动态代理
<?php
class DynamicProxy {
private $target;
private $handlers = [];
public function __construct($target) {
$this->target = $target;
}
public function addHandler($method, callable $handler) {
$this->handlers[$method] = $handler;
}
public function __call($name, $arguments) {
// 检查是否需要前置处理
if (isset($this->handlers['before'])) {
call_user_func_array($this->handlers['before'], [$name, $arguments]);
}
// 调用目标方法
$result = call_user_func_array([$this->target, $name], $arguments);
// 检查是否需要后置处理
if (isset($this->handlers['after'])) {
$result = call_user_func_array($this->handlers['after'], [$name, $arguments, $result]);
}
return $result;
}
}
// 使用
class UserService {
public function getUser($id) {
return "用户信息: " . $id;
}
}
$userService = new UserService();
$proxy = new DynamicProxy($userService);
$proxy->addHandler('before', function($method, $args) {
echo "前置处理: 调用 $method\n";
});
$proxy->addHandler('after', function($method, $args, $result) {
echo "后置处理: $method 返回 $result\n";
return $result;
});
echo $proxy->getUser(123);
访问控制系统
基于角色的访问控制(RBAC)
<?php
class RBAC {
private $roles = [];
private $permissions = [];
private $userRoles = [];
private $rolePermissions = [];
// 添加角色
public function addRole($roleName, $parentRole = null) {
$this->roles[$roleName] = $parentRole;
}
// 添加权限
public function addPermission($permissionName, $description = '') {
$this->permissions[$permissionName] = $description;
}
// 分配角色给用户
public function assignRole($userId, $roleName) {
if (!isset($this->userRoles[$userId])) {
$this->userRoles[$userId] = [];
}
$this->userRoles[$userId][] = $roleName;
}
// 授权角色权限
public function grantPermission($roleName, $permissionName) {
if (!isset($this->rolePermissions[$roleName])) {
$this->rolePermissions[$roleName] = [];
}
$this->rolePermissions[$roleName][] = $permissionName;
}
// 检查用户是否有权限
public function hasPermission($userId, $permissionName) {
if (!isset($this->userRoles[$userId])) {
return false;
}
$roles = $this->userRoles[$userId];
foreach ($roles as $role) {
if ($this->roleHasPermission($role, $permissionName)) {
return true;
}
}
return false;
}
private function roleHasPermission($roleName, $permissionName) {
// 检查当前角色
if (isset($this->rolePermissions[$roleName]) &&
in_array($permissionName, $this->rolePermissions[$roleName])) {
return true;
}
// 检查父角色
if (isset($this->roles[$roleName]) && $this->roles[$roleName] !== null) {
return $this->roleHasPermission($this->roles[$roleName], $permissionName);
}
return false;
}
// 获取用户所有权限
public function getUserPermissions($userId) {
$permissions = [];
if (isset($this->userRoles[$userId])) {
foreach ($this->userRoles[$userId] as $role) {
$permissions = array_merge($permissions, $this->getRolePermissions($role));
}
}
return array_unique($permissions);
}
private function getRolePermissions($roleName) {
$permissions = [];
if (isset($this->rolePermissions[$roleName])) {
$permissions = $this->rolePermissions[$roleName];
}
if (isset($this->roles[$roleName]) && $this->roles[$roleName] !== null) {
$permissions = array_merge($permissions, $this->getRolePermissions($this->roles[$roleName]));
}
return $permissions;
}
}
// 使用示例
$rbac = new RBAC();
// 添加角色
$rbac->addRole('admin');
$rbac->addRole('editor', 'admin');
$rbac->addRole('viewer', 'editor');
// 添加权限
$rbac->addPermission('create_content', '创建内容');
$rbac->addPermission('edit_content', '编辑内容');
$rbac->addPermission('delete_content', '删除内容');
$rbac->addPermission('view_content', '查看内容');
// 分配权限
$rbac->grantPermission('admin', 'create_content');
$rbac->grantPermission('admin', 'edit_content');
$rbac->grantPermission('admin', 'delete_content');
$rbac->grantPermission('admin', 'view_content');
$rbac->grantPermission('editor', 'edit_content');
$rbac->grantPermission('editor', 'view_content');
$rbac->grantPermission('viewer', 'view_content');
// 分配角色给用户
$rbac->assignRole(1, 'admin');
$rbac->assignRole(2, 'editor');
$rbac->assignRole(3, 'viewer');
// 检查权限
echo "用户1是否有创建权限: " . ($rbac->hasPermission(1, 'create_content') ? '是' : '否') . "\n";
echo "用户2是否有删除权限: " . ($rbac->hasPermission(2, 'delete_content') ? '是' : '否') . "\n";
基于属性的访问控制(ABAC)
<?php
class ABAC {
private $policies = [];
private $userAttributes = [];
private $resourceAttributes = [];
private $environmentAttributes = [];
// 添加访问策略
public function addPolicy($policyName, $conditions, $effect = 'allow') {
$this->policies[$policyName] = [
'conditions' => $conditions,
'effect' => $effect
];
}
// 设置用户属性
public function setUserAttributes($userId, $attributes) {
$this->userAttributes[$userId] = $attributes;
}
// 设置资源属性
public function setResourceAttributes($resourceId, $attributes) {
$this->resourceAttributes[$resourceId] = $attributes;
}
// 设置环境属性
public function setEnvironmentAttributes($attributes) {
$this->environmentAttributes = $attributes;
}
// 评估访问请求
public function evaluateAccess($userId, $resourceId, $action) {
foreach ($this->policies as $policy) {
if ($this->evaluateConditions($policy['conditions'], $userId, $resourceId, $action)) {
return $policy['effect'] === 'allow';
}
}
return false; // 默认拒绝
}
private function evaluateConditions($conditions, $userId, $resourceId, $action) {
foreach ($conditions as $condition) {
if (!$this->evaluateCondition($condition, $userId, $resourceId, $action)) {
return false;
}
}
return true;
}
private function evaluateCondition($condition, $userId, $resourceId, $action) {
$attributeValue = $this->getAttributeValue($condition['attribute'], $userId, $resourceId);
switch ($condition['operator']) {
case 'equals':
return $attributeValue === $condition['value'];
case 'greater_than':
return $attributeValue > $condition['value'];
case 'less_than':
return $attributeValue < $condition['value'];
case 'in':
return in_array($attributeValue, $condition['value']);
case 'contains':
return strpos($attributeValue, $condition['value']) !== false;
default:
return false;
}
}
private function getAttributeValue($attribute, $userId, $resourceId) {
// 解析属性路径
$parts = explode('.', $attribute);
switch ($parts[0]) {
case 'user':
return $this->userAttributes[$userId][$parts[1]] ?? null;
case 'resource':
return $this->resourceAttributes[$resourceId][$parts[1]] ?? null;
case 'environment':
return $this->environmentAttributes[$parts[1]] ?? null;
default:
return null;
}
}
}
// 使用示例
$abac = new ABAC();
// 设置用户属性
$abac->setUserAttributes(1, [
'role' => 'admin',
'department' => 'IT',
'clearance_level' => 5
]);
// 设置资源属性
$abac->setResourceAttributes('doc_123', [
'classification' => 'confidential',
'owner' => 1,
'department' => 'IT'
]);
// 设置环境属性
$abac->setEnvironmentAttributes([
'time' => date('H:i'),
'ip_address' => '192.168.1.100'
]);
// 添加策略
$abac->addPolicy('admin_access', [
['attribute' => 'user.role', 'operator' => 'equals', 'value' => 'admin']
], 'allow');
$abac->addPolicy('department_access', [
['attribute' => 'user.department', 'operator' => 'equals', 'value' => 'resource.department'],
['attribute' => 'user.clearance_level', 'operator' => 'greater_than', 'value' => 3]
], 'allow');
// 评估访问
$canAccess = $abac->evaluateAccess(1, 'doc_123', 'read');
echo "用户1是否可以访问文档: " . ($canAccess ? '是' : '否');
中间件式访问控制
<?php
class AccessControlMiddleware {
private $rules = [];
private $userProvider;
public function __construct(callable $userProvider) {
$this->userProvider = $userProvider;
}
// 添加访问规则
public function addRule($path, $requirements, $method = 'GET') {
$this->rules[] = [
'path' => $path,
'method' => $method,
'requirements' => $requirements
];
}
// 处理请求
public function handle($request, callable $next) {
$user = call_user_func($this->userProvider);
foreach ($this->rules as $rule) {
if ($this->matchRule($rule, $request)) {
if (!$this->checkRequirements($rule['requirements'], $user, $request)) {
return $this->denyAccess('无权访问此资源');
}
}
}
return $next($request);
}
private function matchRule($rule, $request) {
$pathMatch = preg_match('#^' . $rule['path'] . '$#', $request['path']);
$methodMatch = strtoupper($rule['method']) === strtoupper($request['method']) ||
$rule['method'] === '*';
return $pathMatch && $methodMatch;
}
private function checkRequirements($requirements, $user, $request) {
foreach ($requirements as $requirement) {
if (!$this->checkRequirement($requirement, $user, $request)) {
return false;
}
}
return true;
}
private function checkRequirement($requirement, $user, $request) {
switch ($requirement['type']) {
case 'role':
return in_array($requirement['value'], $user['roles'] ?? []);
case 'permission':
return in_array($requirement['value'], $user['permissions'] ?? []);
case 'owner':
return $user['id'] === $request['resource_owner'];
case 'ip_whitelist':
return in_array($request['ip'], $requirement['value']);
case 'time_restriction':
$currentTime = time();
return $currentTime >= strtotime($requirement['start']) &&
$currentTime <= strtotime($requirement['end']);
default:
return false;
}
}
private function denyAccess($message) {
http_response_code(403);
echo json_encode(['error' => $message]);
exit;
}
}
// 使用示例
$middleware = new AccessControlMiddleware(function() {
// 从会话或token获取用户信息
return [
'id' => 1,
'username' => 'admin',
'roles' => ['admin', 'editor'],
'permissions' => ['create_post', 'edit_post', 'delete_post']
];
});
// 添加规则
$middleware->addRule('/api/admin/.*', [
['type' => 'role', 'value' => 'admin']
]);
$middleware->addRule('/api/posts/create', [
['type' => 'permission', 'value' => 'create_post']
]);
$middleware->addRule('/api/posts/(\d+)/delete', [
['type' => 'permission', 'value' => 'delete_post'],
['type' => 'owner', 'value' => true]
]);
// 处理请求
$request = [
'path' => '/api/posts/123/delete',
'method' => 'POST',
'ip' => '192.168.1.100',
'resource_owner' => 1
];
$middleware->handle($request, function($req) {
echo "请求处理成功";
});
综合应用示例
完整的代理+访问控制系统
<?php
// 数据库操作代理
class DatabaseProxy {
private $db;
private $accessControl;
private $queryLog = [];
public function __construct(PDO $db, $accessControl) {
$this->db = $db;
$this->accessControl = $accessControl;
}
public function query($sql, $params = []) {
// 检查权限
if (!$this->accessControl->canQuery($sql)) {
throw new Exception("无权执行此查询");
}
// 记录查询
$this->logQuery($sql, $params);
// 执行查询
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
return $stmt;
}
public function insert($table, $data) {
// 检查写入权限
if (!$this->accessControl->canWrite($table)) {
throw new Exception("无权写入此表");
}
// 数据过滤
$filteredData = $this->accessControl->filterData($table, $data);
// 执行插入
$columns = implode(', ', array_keys($filteredData));
$placeholders = ':' . implode(', :', array_keys($filteredData));
$sql = "INSERT INTO $table ($columns) VALUES ($placeholders)";
$stmt = $this->db->prepare($sql);
$stmt->execute($filteredData);
return $this->db->lastInsertId();
}
public function update($table, $data, $where) {
// 检查更新权限
if (!$this->accessControl->canUpdate($table)) {
throw new Exception("无权更新此表");
}
// 数据过滤
$filteredData = $this->accessControl->filterData($table, $data);
// 构建SET子句
$sets = [];
foreach ($filteredData as $column => $value) {
$sets[] = "$column = :$column";
}
$sql = "UPDATE $table SET " . implode(', ', $sets) . " WHERE $where";
$stmt = $this->db->prepare($sql);
$stmt->execute($filteredData);
return $stmt->rowCount();
}
private function logQuery($sql, $params) {
$this->queryLog[] = [
'time' => date('Y-m-d H:i:s'),
'sql' => $sql,
'params' => $params
];
}
public function getQueryLog() {
return $this->queryLog;
}
}
// 文件操作代理
class FileProxy {
private $accessControl;
private $allowedExtensions = ['txt', 'pdf', 'doc', 'docx'];
private $uploadDir = '/uploads/';
public function __construct($accessControl) {
$this->accessControl = $accessControl;
}
public function upload($file, $userId) {
// 检查上传权限
if (!$this->accessControl->canUpload($userId)) {
throw new Exception("无权上传文件");
}
// 检查文件类型
$extension = pathinfo($file['name'], PATHINFO_EXTENSION);
if (!in_array($extension, $this->allowedExtensions)) {
throw new Exception("不支持的文件类型");
}
// 检查文件大小
if ($file['size'] > 10 * 1024 * 1024) { // 10MB
throw new Exception("文件过大");
}
// 生成安全的文件名
$safeName = $this->generateSafeFileName($file['name']);
$targetPath = $this->uploadDir . $userId . '/' . $safeName;
// 创建目录
if (!is_dir(dirname($targetPath))) {
mkdir(dirname($targetPath), 0755, true);
}
// 移动文件
if (move_uploaded_file($file['tmp_name'], $targetPath)) {
return [
'success' => true,
'path' => $targetPath,
'name' => $safeName
];
}
throw new Exception("文件上传失败");
}
public function download($fileId, $userId) {
// 检查下载权限
if (!$this->accessControl->canDownload($fileId, $userId)) {
throw new Exception("无权下载此文件");
}
// 获取文件信息
$fileInfo = $this->getFileInfo($fileId);
// 检查文件是否存在
if (!file_exists($fileInfo['path'])) {
throw new Exception("文件不存在");
}
// 设置下载头
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileInfo['name'] . '"');
header('Content-Length: ' . filesize($fileInfo['path']));
header('Cache-Control: no-cache');
// 输出文件
readfile($fileInfo['path']);
exit;
}
private function generateSafeFileName($originalName) {
$extension = pathinfo($originalName, PATHINFO_EXTENSION);
$baseName = bin2hex(random_bytes(16));
return $baseName . '.' . $extension;
}
private function getFileInfo($fileId) {
// 从数据库获取文件信息
return [
'id' => $fileId,
'name' => 'document.pdf',
'path' => '/uploads/1/document.pdf'
];
}
}
// 使用示例
try {
// 初始化访问控制
$accessControl = new RBAC();
// ... 配置角色和权限
// 数据库代理
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'password');
$dbProxy = new DatabaseProxy($pdo, $accessControl);
// 文件代理
$fileProxy = new FileProxy($accessControl);
// 使用数据库代理
$results = $dbProxy->query("SELECT * FROM users WHERE id = :id", ['id' => 1]);
// 使用文件代理
$fileProxy->upload($_FILES['document'], 1);
} catch (Exception $e) {
echo "错误: " . $e->getMessage();
}
最佳实践
- 分层设计:将代理和访问控制逻辑与业务逻辑分离
- 缓存机制:缓存权限检查结果提高性能
- 日志记录:记录所有访问尝试和权限检查
- 异常处理:完善的错误处理和异常捕获
- 性能优化:使用索引、缓存等技术减少数据库查询
- 安全性:防止SQL注入、XSS攻击等安全威胁
- 可扩展性:设计灵活的角色和权限系统
这些实现提供了完整的PHP项目代理与访问控制解决方案,可以根据实际需求进行定制和扩展。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播