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

2Fa Laravel Package

dragonzap/2fa

Laravel 2FA package with email-based codes by default and optional TOTP for Google/Microsoft Authenticator. Protect routes via the twofactor middleware (always or if-enabled). Publish config, run migrations, and override classes to fully customize the flow.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require dragonzap/2fa
    

    Publish the config file:

    php artisan vendor:publish --provider="DragonZap\TwoFactorAuth\TwoFactorAuthServiceProvider"
    
  2. Configuration Edit config/2fa.php to define:

    • Default provider (totp or backup_codes).
    • TOTP issuer name (e.g., YourAppName).
    • Backup code settings (count, length).
  3. First Use Case: Enable 2FA for a User

    use DragonZap\TwoFactorAuth\Facades\TwoFactorAuth;
    
    // Generate and display QR code for TOTP setup
    $qrCodeUrl = TwoFactorAuth::generateQrCode($user->email, 'YourAppName');
    return view('setup.2fa', compact('qrCodeUrl'));
    
    // Verify TOTP code
    if (TwoFactorAuth::verifyCode($user, $request->input('code'))) {
        $user->is_2fa_enabled = true;
        $user->save();
    }
    

Implementation Patterns

Core Workflows

1. Enabling 2FA

  • TOTP Setup

    // Generate secret and QR code
    $secret = TwoFactorAuth::generateSecret();
    $qrCodeUrl = TwoFactorAuth::generateQrCode($user->email, config('2fa.totp.issuer'));
    
    // Store secret in DB (e.g., `user.totp_secret`)
    $user->totp_secret = $secret;
    $user->save();
    
  • Backup Codes

    // Generate and store backup codes
    $backupCodes = TwoFactorAuth::generateBackupCodes();
    $user->backup_codes = json_encode($backupCodes);
    $user->save();
    

2. Verifying 2FA

  • TOTP Verification

    if (TwoFactorAuth::verifyCode($user, $request->input('code'))) {
        // Grant access
    } else {
        // Show error
    }
    
  • Backup Code Verification

    if (TwoFactorAuth::verifyBackupCode($user, $request->input('backup_code'))) {
        // Grant access and invalidate the code
        TwoFactorAuth::invalidateBackupCode($user, $request->input('backup_code'));
    }
    

3. Middleware Integration

Protect routes with the TwoFactorAuth middleware:

Route::middleware(['auth', '2fa'])->group(function () {
    // Routes requiring 2FA
});

The middleware checks is_2fa_enabled and verifies the current request’s code.

4. Disabling 2FA

$user->is_2fa_enabled = false;
$user->totp_secret = null;
$user->backup_codes = null;
$user->save();

Integration Tips

Database Schema

Extend your users table with:

Schema::table('users', function (Blueprint $table) {
    $table->boolean('is_2fa_enabled')->default(false);
    $table->text('totp_secret')->nullable();
    $table->text('backup_codes')->nullable(); // JSON-encoded array
});

Views

  • Use the generateQrCode() method to render QR codes in Blade:
    {!! TwoFactorAuth::generateQrCodeImage($qrCodeUrl) !!}
    
  • Display backup codes in a user-friendly format (e.g., grid or list).

Logging

Log 2FA events (e.g., setup, verification failures) for security auditing:

if (!TwoFactorAuth::verifyCode($user, $code)) {
    event(new TwoFactorAuthFailed($user->id, $code));
}

Gotchas and Tips

Pitfalls

  1. Secret Storage

    • Gotcha: Storing TOTP secrets in plaintext is secure, but ensure the column is encrypted if compliance requires it.
    • Tip: Use Laravel’s encrypt() when saving/retrieving secrets if additional security is needed.
  2. Backup Code Reuse

    • Gotcha: Backup codes are single-use by default. Reusing a code (e.g., in a UI) may cause false positives.
    • Tip: Explicitly invalidate codes after use:
      TwoFactorAuth::invalidateBackupCode($user, $code);
      
  3. Time Synchronization

    • Gotcha: TOTP relies on device time. Users with incorrect time may fail verification.
    • Tip: Add a "sync time" option in your 2FA setup flow or document the requirement.
  4. Rate Limiting

    • Gotcha: Brute-force attacks on TOTP codes are possible. No built-in rate limiting exists.
    • Tip: Combine with Laravel’s throttle middleware or implement custom logic:
      Route::middleware(['throttle:5,1'])->group(...);
      
  5. Provider Switching

    • Gotcha: The package defaults to TOTP but lacks dynamic provider switching (e.g., toggle between TOTP and backup codes).
    • Tip: Extend the TwoFactorAuth facade or create a custom provider system.

Debugging

  1. Verification Failures

    • Debug Tip: Use TwoFactorAuth::checkCode($user, $code) to manually test codes (returns true/false).
    • Common Causes:
      • Incorrect secret stored in DB.
      • Device time skew (check with date('U')).
      • Code entered too late (TOTP expires every 30s).
  2. QR Code Issues

    • Debug Tip: Verify the issuer and secret in the QR code URL match your config:
      otpauth://totp/YourAppName:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=YourAppName
      
    • Fix: Regenerate the secret if the URL is malformed.
  3. Backup Code Validation

    • Debug Tip: Check if codes are stored as JSON and parsed correctly:
      $codes = json_decode($user->backup_codes, true);
      var_dump(TwoFactorAuth::verifyBackupCode($user, 'TEST123')); // Should return bool
      

Extension Points

  1. Custom Providers

    • Extend the DragonZap\TwoFactorAuth\Contracts\TwoFactorProvider interface to support:
      • SMS-based 2FA.
      • Hardware token integration.
      • Biometric authentication.
  2. Event Hooks

    • Listen for events like TwoFactorAuthGenerated, TwoFactorAuthVerified, or BackupCodeInvalidated:
      TwoFactorAuth::addListener('TwoFactorAuthVerified', function ($user) {
          // Send notification or log event
      });
      
  3. Configuration Overrides

    • Dynamically adjust TOTP settings per user:
      TwoFactorAuth::setTOTPOptions($user, [
          'step' => 30, // Custom time step (default: 30s)
          'digits' => 6,
      ]);
      
  4. Fallback Mechanisms

    • Implement a "recovery mode" for locked-out users:
      if (TwoFactorAuth::isRecoveryModeEnabled($user)) {
          // Allow password fallback or admin intervention
      }
      
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.
babenkoivan/elastic-client
innmind/static-analysis
innmind/coding-standard
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php
agtp/mod-php
centraldesktop/protobuf-php