Filament Login Extra Validation: Check if User is Suspended

2024-12-16

In Filament login form, you may add custom validation rules: for example, check if the user is suspended, and show appropriate validation message.

Let's imagine there is a status column in the user table, and if the status is suspended, the user should receive a validation message.


To make it happen, we need to customize authentication by overwriting the login class.

Create a custom page that needs to extend the base login class from the Filament.

app/Filament/Pages/Auth/Login.php:

namespace App\Filament\Pages\Auth;
 
use Filament\Pages\Auth\Login as BasePage;
 
class Login extends BasePage
{
 
}

This custom login class must be used for the ->login() action in the panel provider.

app/Providers/Filament/AdminPanelProvider.php:

use App\Filament\Pages\Auth\Login;
 
class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->default()
->id('admin')
->path('admin')
->login(Login::class)
// ...
}
}

Then, we override the authenticate() method: we copy-paste its contents from the Base Login and add an additional check, throwing a validation message.

app/Filament/Pages/Auth/Login.php:

use Filament\Facades\Filament;
use Filament\Pages\Auth\Login as BasePage;
use Filament\Models\Contracts\FilamentUser;
use Illuminate\Validation\ValidationException;
use Filament\Http\Responses\Auth\Contracts\LoginResponse;
use DanHarrin\LivewireRateLimiting\Exceptions\TooManyRequestsException;
 
class Login extends BasePage
{
public function authenticate(): ?LoginResponse
{
try {
$this->rateLimit(5);
} catch (TooManyRequestsException $exception) {
$this->getRateLimitedNotification($exception)?->send();
 
return null;
}
 
$data = $this->form->getState();
 
if (! Filament::auth()->attempt($this->getCredentialsFromFormData($data), $data['remember'] ?? false)) {
$this->throwFailureValidationException();
}
 
$user = Filament::auth()->user();
 
if (
($user instanceof FilamentUser) &&
(! $user->canAccessPanel(Filament::getCurrentPanel()))
) {
Filament::auth()->logout();
 
$this->throwFailureValidationException();
} elseif (
$user->status === 'suspended'
) {
Filament::auth()->logout();
 
throw ValidationException::withMessages([
'data.email' => 'Your account is suspended.',
]);
}
 
session()->regenerate();
 
return app(LoginResponse::class);
}
}

A few of our Premium Examples: