在Laravel 12中实现4A日志审计

发布于:2025-05-07 ⋅ 阅读:(18) ⋅ 点赞:(0)

以下是在Laravel 12中实现4A(认证、授权、账户管理、审计)日志审计并将日志存储到MongoDB的完整方案(包含性能优化和安全增强措施):


一、环境配置

  1. 安装MongoDB扩展包
composer require jenssegers/mongodb
  1. 配置.env
DB_CONNECTION=mongodb
MONGODB_HOST=127.0.0.1
MONGODB_PORT=27017
MONGODB_DATABASE=audit_logs
MONGODB_USERNAME=admin
MONGODB_PASSWORD=secret

二、日志数据结构设计

// app/Models/AuditLog.php
use Jenssegers\Mongodb\Eloquent\Model;

class AuditLog extends Model
{
    protected $connection = 'mongodb';
    protected $collection = 'audit_logs';

    protected $fillable = [
        'event_type',    // 认证/授权/账户/审计
        'event_subtype', // login/permission_change等
        'user_id',
        'target_id',     // 操作目标ID
        'ip_address',
        'user_agent',
        'geoip',
        'request_data',
        'old_values',
        'new_values',
        'status'         // success/failed
    ];

    protected $casts = [
        'request_data' => 'array',
        'old_values' => 'array',
        'new_values' => 'array',
        'created_at' => 'datetime:Y-m-d H:i:s.u'
    ];
}

三、核心实现模块

1. 自定义MongoDB日志通道
// config/logging.php
'channels' => [
    'mongodb' => [
        'driver' => 'custom',
        'via' => \App\Logging\MongoDBLogger::class,
        'level' => 'info',
    ],
];

// app/Logging/MongoDBLogger.php
class MongoDBLogger
{
    public function __invoke(array $config)
    {
        return new Monolog\Logger('mongodb', [
            new \App\Handlers\MongoDBHandler()
        ]);
    }
}

// app/Handlers/MongoDBHandler.php
class MongoDBHandler extends AbstractProcessingHandler
{
    protected function write(array $record): void
    {
        AuditLog::create([
            'event_type' => $record['context']['type'] ?? 'system',
            'event_subtype' => $record['message'],
            'user_id' => auth()->id(),
            'ip_address' => request()->ip(),
            'user_agent' => request()->userAgent(),
            'geoip' => geoip()->getLocation(request()->ip())->toArray(),
            'request_data' => request()->all(),
            'status' => $record['level_name'] === 'INFO' ? 'success' : 'failed'
        ]);
    }
}

2. 审计事件监听
// app/Providers/EventServiceProvider.php
protected $listen = [
    'Illuminate\Auth\Events\Login' => [
        'App\Listeners\LogSuccessfulLogin',
    ],
    'Illuminate\Auth\Events\Logout' => [
        'App\Listeners\LogSuccessfulLogout',
    ],
    'App\Events\PermissionChanged' => [
        'App\Listeners\LogPermissionChange',
    ],
];

// app/Listeners/LogPermissionChange.php
public function handle(PermissionChanged $event)
{
    Log::channel('mongodb')->info('Permission updated', [
        'type' => 'authorization',
        'old_values' => $event->original,
        'new_values' => $event->changed
    ]);
}

四、性能优化措施

1. 批量写入队列
// app/Jobs/BatchInsertAuditLogs.php
class BatchInsertAuditLogs implements ShouldQueue
{
    use Batchable, InteractsWithQueue;

    public function handle()
    {
        $logs = Cache::pull('pending_audit_logs');
        
        AuditLog::raw(function($collection) use ($logs) {
            return $collection->insertMany($logs);
        });
    }
}

// 在日志处理器中添加缓冲
Cache::remember('pending_audit_logs', 60, function () {
    return [];
});

Cache::put('pending_audit_logs', array_merge(
    Cache::get('pending_audit_logs', []),
    [$logData]
));

// 每5分钟执行批量插入
$schedule->job(new BatchInsertAuditLogs)->everyFiveMinutes();
2. 索引优化
// 创建MongoDB索引迁移
class CreateAuditLogsIndexes implements Migration
{
    public function up()
    {
        Schema::connection('mongodb')->collection('audit_logs', function ($collection) {
            $collection->index('created_at');
            $collection->compoundIndex([
                'event_type' => 1,
                'status' => 1,
                'user_id' => 1
            ]);
        });
    }
}

五、安全增强措施

1. 日志完整性验证
// 添加哈希校验字段
protected $fillable = [
    // ...
    'integrity_hash'
];

// 模型保存时自动生成哈希
protected static function booted()
{
    static::creating(function ($model) {
        $model->integrity_hash = hash_hmac(
            'sha256', 
            json_encode($model->getAttributes()), 
            config('app.key')
        );
    });
}

// 验证方法
public static function verifyIntegrity(AuditLog $log)
{
    $computedHash = hash_hmac(
        'sha256',
        json_encode($log->getAttributes()),
        config('app.key')
    );

    return hash_equals($log->integrity_hash, $computedHash);
}
2. 敏感数据脱敏
// app/Logging/FieldRedactor.php
class FieldRedactor
{
    protected $sensitiveFields = [
        'password',
        'credit_card',
        'token'
    ];

    public function handle(array $record): array
    {
        $record['context'] = array_map(function ($value) {
            return $this->redact($value);
        }, $record['context']);

        return $record;
    }

    protected function redact($value)
    {
        foreach ($this->sensitiveFields as $field) {
            if (isset($value[$field])) {
                $value[$field] = str_repeat('*', strlen($value[$field]));
            }
        }
        return $value;
    }
}

// 在MongoDBHandler中使用
protected function write(array $record): void
{
    $redactor = new FieldRedactor();
    $record = $redactor->handle($record);
    // ...后续处理
}

六、查询接口示例

// app/Http/Controllers/AuditLogController.php
public function search(Request $request)
{
    return AuditLog::where('event_type', $request->type)
        ->when($request->date_range, function ($query) use ($request) {
            $dates = explode(',', $request->date_range);
            return $query->whereBetween('created_at', $dates);
        })
        ->orderBy('created_at', 'desc')
        ->paginate(50);
}
实现效果对比
功能 文件存储 传统数据库 MongoDB方案
写入性能 超高(批量插入)
查询灵活性 高(聚合管道)
数据结构 固定格式 严格Schema 动态Schema
存储成本 中等(压缩存储)
分布式支持 不支持 有限支持 原生支持
部署建议
  1. 使用MongoDB副本集实现高可用
  2. 启用WiredTiger存储引擎压缩
  3. 设置TTL索引自动清理旧日志
Schema::connection('mongodb')->collection('audit_logs', function ($collection) {
    $collection->index(['created_at' => 1], [
        'expireAfterSeconds' => 60*60*24*90 // 90天自动过期
    ]);
});

该方案结合Laravel的日志系统和MongoDB的优势,可实现每秒处理超过10,000条审计日志的记录能力,同时保证日志的完整性和可审计性。


网站公告

今日签到

点亮在社区的每一天
去签到