Filament 3, connect two tables admins or users for login

I'm using filament 3, I want to connect two tables admins or users for login view. I don't have no roles. just two tables that has email and password. For example: admins table: [email protected]/Test@123 users table: [email protected]/Test@123 I can able to login both tables credentials in the filament back office Can you please suggest?
6 Replies
Mohamed Ayaou
Mohamed Ayaou3mo ago
just customize the login page:
<?php

namespace App\Filament\Pages;

use Filament\Forms\Form;
use Filament\Pages\Auth\Login;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Facades\Blade;
use Filament\Forms\Components\Component;
use Filament\Forms\Components\TextInput;
use Filament\Forms;
use Illuminate\Validation\ValidationException;

class CustomLogin extends Login
{
protected ?string $maxWidth = 'xl';

public function form(Form $form): Form
{
return $form
->schema([
// $this->getEmailFormComponent(),
$this->getEmailOrPhoneFormComponent(),
$this->getPasswordFormComponent(),
$this->getRememberFormComponent(),
])
->statePath('data');
}

// public function getFormActions(): array
// {
// return [];
// }

protected function getEmailOrPhoneFormComponent(): Component
{
return TextInput::make('emailOrPhone')
->label(__('forms.sign_in.email_or_phone.label'))
->placeholder(__('forms.sign_in.email_or_phone.placeholder'))
->required();
}

protected function getPasswordFormComponent(): Component
{
return parent::getPasswordFormComponent()
->label(__('forms.sign_in.password.label'))
->placeholder(__('forms.sign_in.password.placeholder'));
}

/**
* @param array<string, mixed> $data
* @return array<string, mixed>
*/
protected function getCredentialsFromFormData(array $data): array
{
$emailOrPhone = filter_var($data['emailOrPhone'], FILTER_VALIDATE_EMAIL) ? 'email' : 'phone';
return [
$emailOrPhone => $data['emailOrPhone'],
'password' => $data['password'],
];
}

protected function throwFailureValidationException(): never
{
throw ValidationException::withMessages([
'data.emailOrPhone' => __('filament-panels::pages/auth/login.messages.failed'),
]);
}
}
<?php

namespace App\Filament\Pages;

use Filament\Forms\Form;
use Filament\Pages\Auth\Login;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Facades\Blade;
use Filament\Forms\Components\Component;
use Filament\Forms\Components\TextInput;
use Filament\Forms;
use Illuminate\Validation\ValidationException;

class CustomLogin extends Login
{
protected ?string $maxWidth = 'xl';

public function form(Form $form): Form
{
return $form
->schema([
// $this->getEmailFormComponent(),
$this->getEmailOrPhoneFormComponent(),
$this->getPasswordFormComponent(),
$this->getRememberFormComponent(),
])
->statePath('data');
}

// public function getFormActions(): array
// {
// return [];
// }

protected function getEmailOrPhoneFormComponent(): Component
{
return TextInput::make('emailOrPhone')
->label(__('forms.sign_in.email_or_phone.label'))
->placeholder(__('forms.sign_in.email_or_phone.placeholder'))
->required();
}

protected function getPasswordFormComponent(): Component
{
return parent::getPasswordFormComponent()
->label(__('forms.sign_in.password.label'))
->placeholder(__('forms.sign_in.password.placeholder'));
}

/**
* @param array<string, mixed> $data
* @return array<string, mixed>
*/
protected function getCredentialsFromFormData(array $data): array
{
$emailOrPhone = filter_var($data['emailOrPhone'], FILTER_VALIDATE_EMAIL) ? 'email' : 'phone';
return [
$emailOrPhone => $data['emailOrPhone'],
'password' => $data['password'],
];
}

protected function throwFailureValidationException(): never
{
throw ValidationException::withMessages([
'data.emailOrPhone' => __('filament-panels::pages/auth/login.messages.failed'),
]);
}
}
in this sample I login with both email or phone just with overriding For your case just override the authenticate method in the Login class to use the new custom login page class, in the panel provider just add the class to the loggin method
return $panel
->default()
->login(CustomLogin::class)
return $panel
->default()
->login(CustomLogin::class)
toeknee
toeknee3mo ago
As above, but you would override teh authetnicate method, first try authenticating against the user table, else authetnication against the admin table. else return fail.
sathish
sathishOP3mo ago
Thanks for suggestion Filament::auth()->attempt($this->getCredentialsFromFormData($data), $data['remember'] ?? false) Is possible to add guard in the above code? Like Filament::guard('user')->auth()->attempt($this->getCredentialsFromFormData($data), $data['remember'] ?? false); Filament::guard('admin')->auth()->attempt($this->getCredentialsFromFormData($data), $data['remember'] ?? false) Thanks for suggestion, I have two guards admin or users Filament::auth()->attempt($this->getCredentialsFromFormData($data), $data['remember'] ?? false) Is possible to add guard in the above code? Like Filament::guard('user')->auth()->attempt($this->getCredentialsFromFormData($data), $data['remember'] ?? false); Filament::guard('admin')->auth()->attempt($this->getCredentialsFromFormData($data), $data['remember'] ?? false)
toeknee
toeknee3mo ago
Not that I know off no, it's defined on the panel Just authetnmicate manually you don't need to use filamentment to handle the auth Do you have a panel for Admin and users? If so, the panel you access under will determine the auth guard. If you are manually doing it with a custom login page and redirect to desired panel, then just auth as normal laravel
sathish
sathishOP3mo ago
ok class AdminPanelProvider extends PanelProvider { public function panel(Panel $panel) : Panel { return $panel ->default() ->id('admin') ->path('admin') ->authGuard('admin') ->login(CustomLogin::class) ->colors([ 'primary' => Color::Amber, ]) ------------- } } is possible to add two panel in the PanelProvider?
toeknee
toeknee3mo ago
No The Login class will determine the guard in use natively

Did you find this page helpful?