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

Laravel One Time Passwords Laravel Package

spatie/laravel-one-time-passwords

Generate and verify secure one-time passwords (6‑digit by default) in Laravel. Sends OTPs via mail notifications (extendable to SMS/other channels) and includes a Livewire login component. Optional Flux support provides an enhanced OTP input UI.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/laravel-one-time-passwords
    php artisan migrate  # Creates `one_time_passwords` table
    
  2. Publish Config (Optional):

    php artisan vendor:publish --tag="one-time-passwords-config"
    
    • Modify config/one-time-passwords.php for default OTP length, expiration, etc.
  3. First Use Case: Trigger OTP for a user and handle login:

    // In a controller or service
    $user = User::find(1);
    $user->sendOneTimePassword(); // Sends OTP via email (default)
    
    // Later, validate OTP
    $result = $user->attemptLoginUsingOneTimePassword($request->input('otp'));
    if ($result->isOk()) {
        return redirect()->intended('dashboard');
    }
    

Key Files to Review

  • Config: config/one-time-passwords.php (expiration, security rules)
  • Notification: app/Notifications/OneTimePasswordNotification.php (customize email/SMS)
  • Livewire Component: vendor/spatie/laravel-one-time-passwords/src/Livewire/OneTimePassword.php (for UI integration)

Implementation Patterns

Core Workflows

  1. OTP Generation & Delivery:

    // Send OTP via email (default)
    $user->sendOneTimePassword();
    
    // Custom notification (e.g., SMS)
    $user->notify(new CustomOneTimePasswordNotification());
    
  2. OTP Validation:

    // Validate and log in (handles session regeneration)
    $result = $user->attemptLoginUsingOneTimePassword($otp);
    
    // Validate without login (e.g., for passwordless flows)
    $result = $user->consumeOneTimePassword($otp);
    
  3. Livewire Integration:

    <!-- Basic usage (email + OTP form) -->
    <livewire:one-time-password />
    
    <!-- Pre-filled email (skip email step) -->
    <livewire:one-time-password email="user@example.com" />
    
    <!-- Custom redirect -->
    <livewire:one-time-password :redirect-to="route('admin.dashboard')" />
    

Integration Tips

  • Passwordless Auth: Combine with Laravel’s auth:attempt or auth:login after OTP validation:

    if ($result->isOk()) {
        auth()->login($user, $request->has('remember'));
    }
    
  • Rate Limiting: Use Laravel’s throttle middleware or extend the RateLimitExceeded case in ConsumeOneTimePasswordResult.

  • Multi-Channel OTPs: Extend OneTimePasswordNotification to support SMS/Slack:

    class CustomNotification extends OneTimePasswordNotification {
        public function via($notifiable) {
            return ['mail', 'vonage']; // SMS via Vonage
        }
    }
    
  • Testing: Use OneTimePassword::factory() in PHPUnit:

    $otp = OneTimePassword::factory()->create(['password' => '123456']);
    $result = $user->attemptLoginUsingOneTimePassword('123456');
    

Gotchas and Tips

Pitfalls

  1. Origin Enforcement:

    • OTPs default to same-origin validation (IP + User-Agent).
    • Fix: Disable in config or extend EnforceOrigin action class:
      'enforce_origin' => false, // config/one-time-passwords.php
      
  2. Session Hijacking:

    • Always call $request->session()->regenerate() after OTP login to prevent fixation.
  3. Notification Delays:

    • OTPs expire before the notification arrives (default: 2 mins).
    • Tip: Use createOneTimePassword() + manual delivery (e.g., SMS API call) for synchronous flows.
  4. Livewire Caching:

    • The Livewire component caches the email input. Clear it if testing:
      Livewire::test('one-time-password')
          ->set('email', 'test@example.com')
          ->call('sendOneTimePassword');
      

Debugging Tips

  • Check OTP Table:

    SELECT * FROM one_time_passwords WHERE user_id = 1;
    
    • Verify password, expires_at, and ip_address/user_agent match.
  • Log Validation Errors:

    $result->validationMessage(); // Returns user-friendly error
    

    Common messages:

    • "DifferentOrigin" → Check IP/User-Agent.
    • "OneTimePasswordExpired" → Adjust expiration_minutes in config.
  • Custom Actions: Override actions in app/Providers/AppServiceProvider:

    use Spatie\OneTimePasswords\Actions\CreateOneTimePassword;
    use Spatie\OneTimePasswords\Actions\ConsumeOneTimePassword;
    
    public function register()
    {
        $this->app->bind(
            CreateOneTimePassword::class,
            CustomCreateOneTimePassword::class
        );
    }
    

Extension Points

  1. Custom OTP Format: Modify the password field in the OneTimePassword model or use a custom action:

    // Example: Alphanumeric OTP
    $otp = Str::random(8); // Replace default numeric OTP
    
  2. Webhook Validation: Validate OTPs via API (e.g., for server-to-server auth):

    $otp = OneTimePassword::where('password', $request->otp)
        ->where('user_id', $user->id)
        ->first();
    if ($otp && !$otp->isExpired()) {
        $otp->delete(); // Consume
        return response()->json(['success' => true]);
    }
    
  3. Flux Integration: Ensure Flux is installed after the package:

    composer require fluxui/flux
    

    The package auto-detects Flux and uses its OTP input component.

  4. Database Events: Listen for OTP creation/consumption:

    OneTimePassword::created(function ($otp) {
        Log::info("OTP sent to {$otp->user->email}");
    });
    
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.
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
anil/file-picker
broqit/fields-ai