Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Otp Login Laravel Package

taha-moghaddam/filament-otp-login

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require taha-moghaddam/filament-otp-login
    

    Publish the config file:

    php artisan vendor:publish --provider="TahaMoghaddam\FilamentOtpLogin\FilamentOtpLoginServiceProvider"
    
  2. Configure the User Model: Ensure your User model has:

    • A mobile field (string, nullable if not required).
    • A otp_code field (string, nullable).
    • A otp_expires_at field (timestamp, nullable).
    • A 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
    
  3. 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
    
  4. 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
    }
    
  5. Test the Flow:

    • Visit /login and enter a mobile number.
    • The package will redirect to /login/otp?mobile=... with the mobile in the URL.
    • Verify the OTP (default: logged to storage/logs/laravel.log unless configured otherwise).

Implementation Patterns

Workflow: OTP Login Flow

  1. Mobile Submission:

    • User submits a mobile number on /login.
    • The package validates the mobile (configurable regex in config/filament-otp-login.php).
    • Generates an OTP, stores it in the user model, and sends it via the configured OtpSenderInterface.
  2. OTP Verification:

    • Redirects to /login/otp?mobile=... (mobile in URL for statelessness).
    • User enters the OTP code.
    • Validates the code against the stored otp_code and otp_expires_at.
    • Logs in the user if valid; otherwise, shows an error.
  3. Resending OTP:

    • If the user fails verification, they can request a new OTP.
    • Configurable attempts (max_otp_resend_attempts) before a new OTP is generated.

Integration Tips

  • 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
            }
        };
    });
    

Gotchas and Tips

Pitfalls

  1. Mobile Field Requirements:

    • The mobile field in the user model must be nullable if you want to allow optional mobile numbers.
    • Ensure the field is indexed for performance if querying by mobile frequently.
  2. OTP Expiry:

    • The otp_expires_at is set to 5 minutes by default (configurable via otp_expiry_minutes in config).
    • If testing locally, ensure your clock isn’t skewed (e.g., Docker time sync issues).
  3. Session vs. Stateless:

    • The package avoids sessions for the OTP step by passing the mobile in the URL. However, Filament’s core login still uses sessions post-authentication.
    • If you need a completely stateless flow (e.g., for APIs), consider combining this with a custom Filament login page or API routes.
  4. OTP Length and Security:

    • Default OTP length is 6 digits, which may not meet high-security requirements.
    • For production, increase to 8+ digits and use a stronger OtpSenderInterface (e.g., SMS with TOTP).
  5. User Creation:

    • If 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).
    • Customize the creation logic by binding a 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
                  ]);
              }
          };
      });
      
  6. Caching OTPs:

    • The package stores OTPs in the database. For high traffic, consider caching OTPs in Redis with a short TTL (e.g., 5 minutes) and syncing with the DB periodically.
  7. Localization:

    • Error messages (e.g., "Invalid OTP") are hardcoded. Override them by publishing the language file:
      php artisan vendor:publish --tag="filament-otp-login-lang"
      
      Edit resources/lang/en/filament-otp-login.php.

Debugging Tips

  1. OTP Not Received:

    • Check if the OtpSenderInterface is properly bound in the config.
    • Verify the mobile number format matches the regex in config/filament-otp-login.php (default: ^[0-9]{10,15}$).
    • For LogSender, check storage/logs/laravel.log.
  2. User Not Created:

    • Ensure auto_create_user is true in the config.
    • Check if the mobile field is unique (add unique:users,mobile to your users table if needed).
  3. Redirect Loops:

    • If the OTP page redirects unexpectedly, ensure the mobile parameter is correctly passed in the URL (e.g., /login/otp?mobile=1234567890).
    • Clear cached routes if using php artisan route:clear.
  4. Filament Panel Not Recognizing OTP Login:

    • Ensure ->viaOtp() is called in panel()->login().
    • Check for conflicts with other Filament authentication providers (e.g., ->auth()).

Extension Points

  1. Custom OTP Logic:

    • Extend the 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
              }
          };
      });
      
  2. Webhook Verification:

    • Replace the OTP sender with a webhook-based system (e.g., for SMS providers that return delivery status):
      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'
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope