Installation:
composer require chrysanthos/auth-logging
php artisan migrate
create_auth_logs_table) to store failed login attempts.First Use Case:
LoginController@login or LoginController@attemptLogin).AuthLog::log() facade to manually log attempts:
use Chrysanthos\AuthLogging\Facades\AuthLog;
AuthLog::log($credentials, $ip, $userAgent);
Where to Look First:
config/auth-logging.php (if provided; check for customization options like log retention).database/migrations/[timestamp]_create_auth_logs_table.php (schema for auth_logs table).Chrysanthos\AuthLogging\Facades\AuthLog (API reference).Automatic Logging:
AuthenticatesUsers trait (common in LoginController).AuthLog::log() automatically. No manual intervention needed for standard flows.Manual Logging:
try {
$user = Auth::attempt($credentials);
} catch (\Exception $e) {
AuthLog::log($credentials, request()->ip(), request()->userAgent());
}
Querying Logs:
AuthLog model is published or auto-registered):
use Chrysanthos\AuthLogging\Models\AuthLog;
$failedAttempts = AuthLog::where('email', 'user@example.com')
->latest()
->limit(10)
->get();
Integration with Events:
auth.failed events to enrich logs:
use Chrysanthos\AuthLogging\Facades\AuthLog;
use Illuminate\Auth\Events\Failed;
Failed::listen(function (Failed $event) {
AuthLog::log([
'email' => $event->credentials->get('email'),
'password' => '[redacted]',
], $event->request->ip(), $event->request->userAgent());
});
API/SPA Use:
POST /api/login):
Route::post('/api/login', function () {
$credentials = request()->only(['email', 'password']);
if (!Auth::attempt($credentials)) {
AuthLog::log($credentials, request()->ip(), request()->header('User-Agent'));
return response()->json(['error' => 'Invalid credentials'], 401);
}
});
Bulk Actions:
php artisan auth-logging:purge --days=30
Password Storage:
AuthLog::log([
'email' => $credentials['email'],
'password' => '[redacted]',
], $ip, $userAgent);
password_hash column).Missing Config:
php artisan vendor:publish --tag=auth-logging-config
Event Hooks:
handleUserAttemptingAuthenticate or validateCredentials methods.Performance:
if (Auth::hasTooManyLoginAttempts($request)) {
AuthLog::log($credentials, $ip, $userAgent);
}
Database Schema:
failed_at timestamp, guard name).Schema::table('auth_logs', function (Blueprint $table) {
$table->string('guard')->default('web');
$table->timestamp('failed_at')->useCurrent();
});
Testing:
public function test_failed_login_logs_credentials()
{
$response = $this->post('/login', ['email' => 'test@example.com', 'password' => 'wrong']);
$this->assertDatabaseHas('auth_logs', [
'email' => 'test@example.com',
]);
}
Enrich Logs:
device_info or location (via IP geolocation):
AuthLog::log($credentials, $ip, $userAgent, [
'location' => $this->getLocationFromIp($ip),
]);
Alerting:
if ($attempts > 5) {
AuthLog::log($credentials, $ip, $userAgent);
$admin->notify(new BruteForceAlert($ip, $credentials['email']));
}
Custom Models:
AuthLog model to add scopes:
namespace App\Models;
use Chrysanthos\AuthLogging\Models\AuthLog as BaseAuthLog;
class AuthLog extends BaseAuthLog
{
public function scopeForIp($query, $ip)
{
return $query->where('ip', $ip);
}
}
API Responses:
if (AuthLog::where('email', $email)->count() > 4) {
return response()->json(['error' => 'Too many attempts'], 429);
}
Audit Trails:
spatie/laravel-activitylog to track admin actions on failed logins:
event(new Failed($event->user, $credentials));
How can I help you explore Laravel packages today?