neelkanthk/laravel-surveillance
Monitor and control suspicious users in Laravel: track IPs and browser fingerprints, write surveillance logs, and block/allow access. Includes route middleware, CLI commands, and a fluent API; storage is extensible (MySQL by default).
Installation:
composer require neelkanthk/laravel-surveillance
php artisan vendor:publish --provider="Neelkanth\Laravel\Surveillance\Providers\SurveillanceServiceProvider" --tag="migrations"
php artisan vendor:publish --provider="Neelkanth\Laravel\Surveillance\Providers\SurveillanceServiceProvider" --tag="config"
php artisan migrate
First Use Case:
php artisan surveillance:enable ip 192.168.1.1
Route::middleware(['surveillance'])->group(function () {
// Protected routes
});
Where to Look First:
config/surveillance.php (customize fingerprint-header-key or override repositories).php artisan surveillance:.Middleware Integration:
surveillance middleware to route groups or individual routes to log requests for monitored entities (IPs, user IDs, or fingerprints).Route::middleware(['auth', 'surveillance'])->get('/admin', 'AdminController@index');
Programmatic Control:
Surveillance facade for runtime adjustments:
// Enable surveillance for a user ID
Surveillance::manager()->type('userid')->value(123)->enableSurveillance();
// Block a fingerprint
Surveillance::manager()->type('fingerprint')->value('abc123')->blockAccess();
// Log a request (auto-populates with request data)
Surveillance::logger()->writeLog();
CLI Workflows:
# Disable surveillance for a range of IPs (requires custom script)
php artisan surveillance:disable ip 192.168.1.0/24
Event-Driven Logging:
SurveillanceLogRepository to log custom events (e.g., failed payments, brute-force attempts):
// In an event listener
Surveillance::logger()->setLogToWrite([
'event' => 'payment_failed',
'details' => $payment->toArray()
])->writeLog();
Browser Fingerprinting:
fingerprint-header-key).FingerprintJS.load().then(fp => fp.get()).then(result => {
fetch('/set-fingerprint', {
method: 'POST',
headers: { 'fingerprint': result.visitorId }
});
});
Custom Storage:
SurveillanceManagerRepository or SurveillanceLogRepository to use Redis, Elasticsearch, or a custom database:
// config/surveillance.php
'manager-repository' => App\Repositories\RedisSurveillanceManager::class,
'log-repository' => App\Repositories\ElasticSurveillanceLogger::class,
Laravel Events:
illuminate\auth\events\Failed):
use Neelkanth\Laravel\Surveillance\Facades\Surveillance;
event(new Failed($request, $credentials));
Surveillance::logger()->writeLog(['event' => 'auth.failed', 'attempt' => $request->input('email')]);
API Rate Limiting:
if (request()->ip() === '192.168.1.100') {
Surveillance::manager()->type('ip')->value(request()->ip())->blockAccess();
abort(429, 'Access blocked');
}
Performance Overhead:
Surveillance::logger()->queueLog()) or limit log retention via database indexes:
// Add to SurveillanceLogs migration
$table->index(['created_at']);
False Positives:
Fingerprint Collisions:
Middleware Order:
app/Http/Kernel.php:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\Authenticate::class,
\Neelkanth\Laravel\Surveillance\Http\Middleware\Surveillance::class,
// ...
],
];
Database Locking:
surveillance:block) may cause race conditions.DB::transaction(function () {
Surveillance::manager()->type('ip')->value('192.168.1.1')->blockAccess();
});
Log Inspection:
surveillance_logs table to verify logs:
SELECT * FROM surveillance_logs WHERE type = 'ip' AND value = '192.168.1.1' ORDER BY created_at DESC;
Middleware Debugging:
// In SurveillanceMiddleware.php
public function handle($request, Closure $next) {
\Log::info('Surveillance middleware triggered for IP: ' . $request->ip());
return $next($request);
}
CLI Command Errors:
userid vs. user_id):
php artisan surveillance:enable userid 123 # Correct
php artisan surveillance:enable user_id 123 # Fails
Combine with Laravel Policies:
public function authorize(Role $role) {
if (Surveillance::manager()->type('userid')->value(auth()->id())->isBlocked()) {
abort(403);
}
return $role->isAdmin();
}
Automate Surveillance:
// app/Console/Kernel.php
protected function schedule(Schedule $schedule) {
$schedule->command('surveillance:disable ip 192.168.1.100')->dailyAt('03:00');
}
Custom Log Fields:
SurveillanceLogRepository to include additional metadata:
public function writeLog($data = []) {
$data['custom_field'] = 'value';
parent::writeLog($data);
}
UI Integration:
Testing:
Surveillance facade in tests:
Surveillance::shouldReceive('logger()->writeLog')->once();
How can I help you explore Laravel packages today?