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

Passwordless Login Laravel Package

spykapps/passwordless-login

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require spykapps/passwordless-login
    php artisan vendor:publish --tag=passwordless-login-config
    php artisan vendor:publish --tag=passwordless-login-migrations
    php artisan migrate
    
  2. Add Trait to User Model:

    use SpykApp\PasswordlessLogin\Traits\HasMagicLogin;
    
    class User extends Authenticatable
    {
        use HasMagicLogin;
    }
    
  3. Send Magic Link in Controller:

    use SpykApp\PasswordlessLogin\Facades\PasswordlessLogin;
    
    public function sendMagicLink(Request $request)
    {
        $request->validate(['email' => 'required|email']);
        $user = User::where('email', $request->email)->first();
    
        if (!$user) {
            return back()->with('status', __('passwordless-login::messages.link_sent_if_exists'));
        }
    
        try {
            $user->sendMagicLink($request);
        } catch (\SpykApp\PasswordlessLogin\Exceptions\ThrottleException $e) {
            return back()->with('error', $e->getMessage());
        }
    
        return back()->with('status', __('passwordless-login::messages.link_sent'));
    }
    
  4. Configure Routes (auto-registered): Ensure your routes/web.php includes the guest middleware for the /magic-login/{token} route.

First Use Case

Replace traditional login forms with a passwordless flow for user onboarding or guest access. Example:

// In a registration controller
$user = User::create($validatedData);
$user->sendMagicLink($request);
return redirect()->route('verify.email');

Implementation Patterns

Core Workflows

  1. Magic Link Generation:

    // Fluent API for full control
    $result = PasswordlessLogin::forUser($user)
        ->guard('admin')
        ->expiresIn(30)
        ->maxUses(1)
        ->generate($request);
    
    // Or via trait (simplest)
    $user->sendMagicLink($request);
    
  2. Multi-Channel Delivery:

    // Generate without email for SMS/WhatsApp
    $result = PasswordlessLogin::forUser($user)
        ->withoutNotification()
        ->generate($request);
    
    // Send via Twilio/SMS
    $this->smsService->send($user->phone, $result['url']);
    
  3. Conditional Authentication:

    // In config/passwordless-login.php
    'conditions' => [
        fn($user) => $user->is_active,
        \App\Auth\CheckSubscription::class,
    ];
    
  4. Post-Login Actions:

    // In config/passwordless-login.php
    'after_login_action' => \App\Actions\UpdateLastLogin::class;
    

Integration Tips

  • API Integration: Use withoutNotification() for API-based magic links, then manually send the URL via API response:

    { "magic_link": "https://your-app.com/magic-login/abc123" }
    
  • Custom Notifications: Extend the default notification by publishing views:

    php artisan vendor:publish --tag=passwordless-login-views
    

    Then override resources/views/vendor/passwordless-login/email.blade.php.

  • Rate Limiting: Customize throttling in config:

    'throttle' => [
        'max_attempts' => 3,
        'decay_minutes' => 5,
    ],
    
  • Bot Mitigation: Use the javascript strategy for auto-redirects (requires JS):

    'bot_detection' => [
        'strategy' => 'javascript',
    ],
    
  • Testing: Mock the PasswordlessLogin facade in tests:

    $this->partialMock(PasswordlessLogin::class, function ($mock) {
        $mock->shouldReceive('forUser')
             ->andReturnSelf()
             ->shouldReceive('generate')
             ->andReturn(['url' => 'test-url']);
    });
    

Gotchas and Tips

Pitfalls

  1. Token Expiry:

    • Default expiry is 15 minutes. Adjust in config if needed:
      'expiry_minutes' => 60, // 1 hour
      
    • Debugging: Check passwordless_login_tokens table for expires_at timestamps.
  2. Bot Detection False Positives:

    • If legitimate users are blocked, adjust the strategy or disable temporarily:
      'bot_detection' => ['enabled' => false],
      
    • Log bot events to debug:
      Event::listen(\SpykApp\PasswordlessLogin\Events\BotDetected::class, function ($event) {
          Log::debug('Bot detected:', $event->request->userAgent());
      });
      
  3. Rate Limiting:

    • Throttle exceptions may not reveal if the user exists (security feature). Handle generically:
      try {
          $user->sendMagicLink($request);
      } catch (ThrottleException $e) {
          return back()->with('error', 'Too many requests. Try again later.');
      }
      
  4. Token Security:

    • IP/UA Binding: Enable only if needed (adds friction):
      'security' => [
          'ip_binding' => true,
          'user_agent_binding' => true,
      ],
      
    • Token Length: Increase for higher security (default 32 bytes):
      'token' => ['length' => 64],
      
  5. Event Order:

    • MagicLinkClicked fires before MagicLinkAuthenticated. Use the former for bot checks:
      Event::listen(MagicLinkClicked::class, function ($event) {
          if ($event->isBotDetected) {
              abort(403, 'Access denied.');
          }
      });
      

Debugging Tips

  • Token Validation: Check the used_at and expires_at columns in the tokens table. Manually invalidate tokens with:

    $token = \SpykApp\PasswordlessLogin\Models\MagicLoginToken::find($id);
    $token->delete(); // Or set `used_at = now()`.
    
  • Route Issues: Ensure the /magic-login/{token} route is not overridden. Verify with:

    php artisan route:list | grep magic-login
    
  • Notification Failures: Check the failed_jobs table if emails aren’t sent. Queue notifications explicitly:

    'notification' => ['queue' => true],
    
  • Custom Guard: If using a custom guard (e.g., admin), ensure it’s registered in auth.php:

    'guards' => [
        'admin' => ['driver' => 'session', 'provider' => 'admins'],
    ],
    

Extension Points

  1. Custom Token Model: Extend \SpykApp\PasswordlessLogin\Models\MagicLoginToken and bind it in config:

    'model' => \App\Models\CustomMagicLoginToken::class,
    
  2. Dynamic Conditions: Add runtime conditions via middleware:

    public function handle($request, Closure $next)
    {
        if ($request->has('temp_access')) {
            config(['passwordless-login.conditions' => [
                fn($user) => $user->isTempAccessAllowed(),
            ]]);
        }
        return $next($request);
    }
    
  3. Token Metadata: Attach custom data to tokens for tracking:

    $result = PasswordlessLogin::forUser($user)
        ->withMetadata(['campaign' => 'black_friday'])
        ->generate($request);
    

    Access later via $token->metadata.

  4. Override Views: Publish and customize:

    php artisan vendor:publish --tag=passwordless-login-views
    

    Override:

    • resources/views/vendor/passwordless-login/email.blade.php
    • resources/views/vendor/passwordless-login/confirmation.blade.php (for bot detection).
  5. Audit Logging: Extend the audit log by implementing \SpykApp\PasswordlessLogin\Contracts\AuditLogger:

    class SlackAuditLogger implements AuditLogger
    {
        public function log($event, $data)
        {
            // Send to Slack
        }
    }
    

    Bind in config:

    'audit_log' => \App\Services\SlackAuditLogger::class,
    
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.
supportpal/coding-standard
act-training/query-builder
labrodev/php-mixed-converter
nebo15/lumen.rest
nqxcode/lucene-stemmer-en-ru
nqxcode/zendsearch
erlandmuchasaj/laravel-gzip
iio/libmergepdf
redaxo/project
zatona-eg/zatona-eg-api
patrickbussmann/oauth2-apple
3brs/enterprise-security-bundle
ardenexal/fhir-models
ardenexal/fhir-validation
dpfx/laravel-livewire-wizards
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle