How to auto-login in local environment, with a user selector

The problem
It's very, very annoying when we deal dozens of times interacting with our app in development, and we have to fill the login form. Not only we have to type the same thing over and over, there's also the muscle memory needed to remember the different users (with different roles, etc.).
What we explore today is a very convenient way of logging in an existing user after our migrations and seeders run..
The solution
Only in the local environment, we will override the default Filament login page, to add a dropdown with all the users available in our system. This way, we can just select the user we want to log in as, and click the login button.
Let's create a Filament Page class only. Instead of running the command, we will create the file manually, to avoid
creating the view. Here's a shortcut to create the folder and file app/Filament/Pages/Auth/Login.php:
mkdir -p app/Filament/Pages/Auth
touch app/Filament/Pages/Auth/Login.php
We can now copy the contents of the file, that will override the default form.
<?php
namespace App\Filament\Pages\Auth;
use App\Models\User;
use Filament\Forms\Components\Select;
use Filament\Forms\Form;
use Filament\Pages\Auth\Login as BasePage;
use Filament\Http\Responses\Auth\Contracts\LoginResponse;
class Login extends BasePage
{
public function mount(): void
{
parent::mount();
}
public function form(Form $form): Form
{
if (app()->environment('local')) {
$users = User::query()
->whereLike('email', '%@example.com')
->pluck('name', 'email');
$defaultUserEmail = User::query()
->whereLike('email', '%@example.com')
->first()?->email;
$form->schema([
Select::make('user')
->required()
->options($users)
->default($defaultUserEmail),
]);
return $form;
}
return parent::form($form);
}
public function authenticate(): ?LoginResponse
{
if (app()->environment('local')) {
$authenticateAs = $this->form->getState()['user'] ?? null;
auth()->login(
User::query()
->whereLike('email', '%@example.com')
->where('email', $authenticateAs)->first()
);
return app(LoginResponse::class);
}
return parent::authenticate();
}
}
We also need to tell Filament to use this new Login page.
<?php
namespace App\Providers\Filament;
use App\Filament\Pages\Auth\Login;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\AuthenticateSession;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Pages;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Colors\Color;
use Filament\Widgets;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->default()
->id('admin')
->path('admin')
->login(Login::class)
->colors([
'primary' => Color::Amber,
])
->viteTheme('resources/css/filament/admin/theme.css')
->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources')
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
->pages([
Pages\Dashboard::class,
])
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
->widgets([
Widgets\AccountWidget::class,
Widgets\FilamentInfoWidget::class,
])
->middleware([
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
])
->authMiddleware([
Authenticate::class,
]);
}
}
We'll be able to have our seeded users ready to be selected in the dropdown:

We're done. Enjoy!