taha-moghaddam/filament-otp-login
Install the package:
composer require taha-moghaddam/filament-otp-login
Publish the config file:
php artisan vendor:publish --provider="TahaMoghaddam\FilamentOtpLogin\FilamentOtpLoginServiceProvider"
Configure the User Model:
Ensure your User model has:
mobile field (string, nullable if not required).otp_code field (string, nullable).otp_expires_at field (timestamp, nullable).otp_attempts field (integer, default 0).Run migrations if needed (adjust as required):
php artisan make:migration add_otp_fields_to_users_table --table=users
Configure the Package:
Update config/filament-otp-login.php:
'otp_length' => 6,
'request_block_seconds' => 60,
'max_otp_resend_attempts' => 3,
'sender' => \TahaMoghaddam\FilamentOtpLogin\Senders\LogSender::class, // Default: LogSender
Register the Login Method: Add the OTP login to your Filament panel’s authentication:
// app/Providers/Filament/AdminPanelProvider.php
public function panel(Panel $panel): Panel
{
return $panel
->login()
->viaOtp(); // Add this line
}
Test the Flow:
/login and enter a mobile number./login/otp?mobile=... with the mobile in the URL.storage/logs/laravel.log unless configured otherwise).Mobile Submission:
/login.config/filament-otp-login.php).OtpSenderInterface.OTP Verification:
/login/otp?mobile=... (mobile in URL for statelessness).otp_code and otp_expires_at.Resending OTP:
max_otp_resend_attempts) before a new OTP is generated.Custom OTP Sender:
Implement OtpSenderInterface and bind it in the config:
// Example: SMS Sender
use TahaMoghaddam\FilamentOtpLogin\Senders\OtpSenderInterface;
class SmsSender implements OtpSenderInterface {
public function send(string $mobile, string $otp): void {
// Logic to send SMS via Twilio, AWS SNS, etc.
}
}
Update config:
'sender' => \App\Services\SmsSender::class,
Custom Validation: Override the default mobile validation by publishing and modifying the request class:
php artisan vendor:publish --tag="filament-otp-login-requests"
Edit app/Http/Requests/FilamentOtpLogin/StoreMobileRequest.php.
First-Time Registration: The package automatically creates a user if the mobile doesn’t exist (configurable):
'auto_create_user' => true, // Default: true
Rate Limiting:
Use the request_block_seconds config to prevent spam:
'request_block_seconds' => 120, // 2 minutes
Testing:
Use the LogSender for testing (default) or mock the OtpSenderInterface in PHPUnit:
$this->app->bind(OtpSenderInterface::class, function () {
return new class implements OtpSenderInterface {
public function send(string $mobile, string $otp): void {
// Mock logic
}
};
});
Mobile Field Requirements:
mobile field in the user model must be nullable if you want to allow optional mobile numbers.OTP Expiry:
otp_expires_at is set to 5 minutes by default (configurable via otp_expiry_minutes in config).Session vs. Stateless:
OTP Length and Security:
OtpSenderInterface (e.g., SMS with TOTP).User Creation:
auto_create_user is true, the package creates a user on first OTP login. Ensure your User model’s fillable includes the required fields (e.g., mobile, name).UserCreatorInterface:
$this->app->bind(\TahaMoghaddam\FilamentOtpLogin\Contracts\UserCreatorInterface::class, function () {
return new class implements UserCreatorInterface {
public function create(array $data): \App\Models\User {
return \App\Models\User::create([
'mobile' => $data['mobile'],
'name' => 'Guest ' . $data['mobile'],
// Add other default fields
]);
}
};
});
Caching OTPs:
Localization:
php artisan vendor:publish --tag="filament-otp-login-lang"
Edit resources/lang/en/filament-otp-login.php.OTP Not Received:
OtpSenderInterface is properly bound in the config.config/filament-otp-login.php (default: ^[0-9]{10,15}$).LogSender, check storage/logs/laravel.log.User Not Created:
auto_create_user is true in the config.unique:users,mobile to your users table if needed).Redirect Loops:
mobile parameter is correctly passed in the URL (e.g., /login/otp?mobile=1234567890).php artisan route:clear.Filament Panel Not Recognizing OTP Login:
->viaOtp() is called in panel()->login().->auth()).Custom OTP Logic:
OtpGenerator class to implement custom OTP generation (e.g., alphanumeric codes):
$this->app->bind(\TahaMoghaddam\FilamentOtpLogin\Contracts\OtpGeneratorInterface::class, function () {
return new class implements OtpGeneratorInterface {
public function generate(): string {
return Str::random(8); // Alphanumeric OTP
}
};
});
Webhook Verification:
class WebhookSender implements OtpSenderInterface {
public function send(string $mobile, string $otp): void {
Http::post('https://sms-provider.com/send', [
'mobile' => $mobile,
'otp' => $otp,
'callback_url'
How can I help you explore Laravel packages today?