本文目录导读:

我来详细说明PHP权限日志的实现方法:
基础权限日志系统
数据库表结构
CREATE TABLE permission_logs (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
username VARCHAR(50),
action VARCHAR(50) NOT NULL,
resource VARCHAR(100),
resource_id INT,
status TINYINT(1) DEFAULT 1, -- 1成功 0失败
ip_address VARCHAR(45),
user_agent TEXT,
detail TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id),
INDEX idx_action (action),
INDEX idx_created_at (created_at)
);
PHP实现类
<?php
class PermissionLogger {
private $db;
private $logConfig;
public function __construct($dbConnection) {
$this->db = $dbConnection;
$this->logConfig = [
'enabled' => true,
'log_level' => 'info', // error, warning, info, debug
'retention_days' => 90,
'log_methods' => ['database', 'file'] // 支持多种存储方式
];
}
/**
* 记录权限日志
*/
public function log($userId, $action, $resource, $resourceId = null,
$status = true, $detail = null) {
try {
if (!$this->logConfig['enabled']) {
return false;
}
// 获取用户信息
$userInfo = $this->getUserInfo($userId);
$logData = [
'user_id' => $userId,
'username' => $userInfo['username'] ?? 'Unknown',
'action' => $action,
'resource' => $resource,
'resource_id' => $resourceId,
'status' => $status ? 1 : 0,
'ip_address' => $this->getClientIP(),
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
'detail' => $detail ? json_encode($detail) : null,
'created_at' => date('Y-m-d H:i:s')
];
// 保存到数据库
$this->saveToDatabase($logData);
// 保存到文件
if (in_array('file', $this->logConfig['log_methods'])) {
$this->saveToFile($logData);
}
return true;
} catch (Exception $e) {
error_log("Permission log error: " . $e->getMessage());
return false;
}
}
/**
* 保存到数据库
*/
private function saveToDatabase($data) {
$sql = "INSERT INTO permission_logs
(user_id, username, action, resource, resource_id,
status, ip_address, user_agent, detail, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $this->db->prepare($sql);
$stmt->execute([
$data['user_id'],
$data['username'],
$data['action'],
$data['resource'],
$data['resource_id'],
$data['status'],
$data['ip_address'],
$data['user_agent'],
$data['detail'],
$data['created_at']
]);
}
/**
* 保存到文件
*/
private function saveToFile($data) {
$logDir = __DIR__ . '/logs/permission/';
if (!is_dir($logDir)) {
mkdir($logDir, 0755, true);
}
$logFile = $logDir . date('Y-m-d') . '.log';
$logLine = sprintf(
"[%s] [%s] [User:%s] [Action:%s] [Resource:%s] [Status:%s] [IP:%s] %s\n",
$data['created_at'],
$data['status'] ? 'SUCCESS' : 'FAILURE',
$data['username'],
$data['action'],
$data['resource'] . ($data['resource_id'] ? "({$data['resource_id']})" : ''),
$data['status'] ? 'Allowed' : 'Denied',
$data['ip_address'],
$data['detail'] ?: ''
);
file_put_contents($logFile, $logLine, FILE_APPEND | LOCK_EX);
}
/**
* 获取客户端IP
*/
private function getClientIP() {
$ipKeys = [
'HTTP_X_FORWARDED_FOR',
'HTTP_X_REAL_IP',
'HTTP_CLIENT_IP',
'REMOTE_ADDR'
];
foreach ($ipKeys as $key) {
if (isset($_SERVER[$key])) {
$ip = $_SERVER[$key];
if (filter_var($ip, FILTER_VALIDATE_IP)) {
return $ip;
}
}
}
return '0.0.0.0';
}
/**
* 获取用户信息
*/
private function getUserInfo($userId) {
// 这里应该从用户表查询
$sql = "SELECT id, username, role FROM users WHERE id = ?";
$stmt = $this->db->prepare($sql);
$stmt->execute([$userId]);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
}
权限检查与日志记录中间件
<?php
class PermissionMiddleware {
private $logger;
private $permissions;
public function __construct($db) {
$this->logger = new PermissionLogger($db);
$this->permissions = [
'admin' => ['create', 'read', 'update', 'delete'],
'editor' => ['create', 'read', 'update'],
'viewer' => ['read']
];
}
/**
* 检查权限并记录日志
*/
public function checkPermission($userId, $requiredAction, $resource) {
try {
// 获取用户角色
$userRole = $this->getUserRole($userId);
// 检查权限
$hasPermission = $this->hasPermission($userRole, $requiredAction);
// 记录权限检查日志
$this->logger->log(
$userId,
$hasPermission ? 'PERMISSION_CHECK' : 'PERMISSION_DENIED',
$resource,
null,
$hasPermission,
[
'role' => $userRole,
'required_action' => $requiredAction,
'has_permission' => $hasPermission
]
);
if (!$hasPermission) {
throw new \Exception("权限不足:需要 {$requiredAction} 权限");
}
return true;
} catch (Exception $e) {
// 记录异常
$this->logger->log(
$userId,
'PERMISSION_ERROR',
$resource,
null,
false,
['error' => $e->getMessage()]
);
throw $e;
}
}
private function getUserRole($userId) {
// 从数据库查询用户角色
$sql = "SELECT role FROM users WHERE id = ?";
$stmt = $this->db->prepare($sql);
$stmt->execute([$userId]);
return $stmt->fetchColumn();
}
private function hasPermission($role, $action) {
return isset($this->permissions[$role]) &&
in_array($action, $this->permissions[$role]);
}
}
使用示例
<?php
// 初始化
$db = new PDO('mysql:host=localhost;dbname=test', 'root', 'password');
$permissionLog = new PermissionLogger($db);
$permissionMiddleware = new PermissionMiddleware($db);
// 记录简单的权限操作
$permissionLog->log(
1, // 用户ID
'LOGIN', // 操作类型
'system', // 资源
null, // 资源ID
true, // 是否成功
['login_method' => 'password'] // 详细信息
);
// 记录文件访问权限
$permissionLog->log(
2,
'FILE_ACCESS',
'document',
123,
true,
['file_path' => '/uploads/document.pdf', 'action' => 'download']
);
// 使用中间件检查权限
try {
$permissionMiddleware->checkPermission(
$userId,
'delete',
'article'
);
// 执行删除操作
} catch (Exception $e) {
echo $e->getMessage();
}
日志管理功能
<?php
class PermissionLogManager {
private $db;
public function __construct($db) {
$this->db = $db;
}
/**
* 查询权限日志
*/
public function queryLogs($filters = [], $page = 1, $perPage = 20) {
$where = [];
$params = [];
if (!empty($filters['user_id'])) {
$where[] = "user_id = ?";
$params[] = $filters['user_id'];
}
if (!empty($filters['action'])) {
$where[] = "action = ?";
$params[] = $filters['action'];
}
if (!empty($filters['status'])) {
$where[] = "status = ?";
$params[] = $filters['status'];
}
if (!empty($filters['date_from'])) {
$where[] = "created_at >= ?";
$params[] = $filters['date_from'];
}
if (!empty($filters['date_to'])) {
$where[] = "created_at <= ?";
$params[] = $filters['date_to'];
}
$whereClause = $where ? 'WHERE ' . implode(' AND ', $where) : '';
// 计算总数
$countSql = "SELECT COUNT(*) FROM permission_logs {$whereClause}";
$countStmt = $this->db->prepare($countSql);
$countStmt->execute($params);
$total = $countStmt->fetchColumn();
// 获取分页数据
$offset = ($page - 1) * $perPage;
$sql = "SELECT * FROM permission_logs {$whereClause}
ORDER BY created_at DESC LIMIT ? OFFSET ?";
$params[] = $perPage;
$params[] = $offset;
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
$logs = $stmt->fetchAll(PDO::FETCH_ASSOC);
return [
'total' => $total,
'page' => $page,
'per_page' => $perPage,
'data' => $logs
];
}
/**
* 清理过期日志
*/
public function cleanOldLogs($days = 90) {
$sql = "DELETE FROM permission_logs WHERE created_at < DATE_SUB(NOW(), INTERVAL ? DAY)";
$stmt = $this->db->prepare($sql);
return $stmt->execute([$days]);
}
/**
* 导出日志
*/
public function exportLogs($filters = []) {
$logs = $this->queryLogs($filters, 1, 1000000);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="permission_logs.csv"');
$output = fopen('php://output', 'w');
fputcsv($output, ['ID', 'User', 'Action', 'Resource', 'Status', 'IP', 'Time']);
foreach ($logs['data'] as $log) {
fputcsv($output, [
$log['id'],
$log['username'],
$log['action'],
$log['resource'] . ' (' . $log['resource_id'] . ')',
$log['status'] ? 'Success' : 'Failed',
$log['ip_address'],
$log['created_at']
]);
}
fclose($output);
exit;
}
}
性能优化建议
- 使用消息队列:对于高并发场景,将日志写入内存队列
- 定期归档:将旧日志归档到单独的表或文件
- 索引优化:在常用查询字段上建立索引
- 缓存热点数据:使用Redis缓存最近的日志
安全考虑
- 对敏感信息进行脱敏处理
- 日志文件权限设置为600
- 限制日志查询的访问权限
- 对日志API进行速率限制
这个系统可以帮助你全面记录和管理权限相关的操作,便于审计和问题排查。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播