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

Lara2Fa Laravel Package

mustafa-awami/lara2fa

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require mustafa-awami/lara2fa
    php artisan vendor:publish --provider="MustafaAwami\Lara2fa\Lara2faServiceProvider" --tag="migrations"
    php artisan migrate
    
    • Publishes migrations for users table (adds two_factor_secret, two_factor_enabled, recovery_codes, passkey_credentials columns).
  2. Configure:

    • Publish config:
      php artisan vendor:publish --provider="MustafaAwami\Lara2fa\Lara2faServiceProvider" --tag="config"
      
    • Key settings in config/lara2fa.php:
      • otp (Email OTP): length, expire_minutes, attempts.
      • totp: issuer, algorithm (SHA1/SHA256/SHA512).
      • passkey: rp_name, rp_id, timeout_seconds.
      • recovery_codes: count, expiry_days.
  3. First Use Case: Enable 2FA for a user via TOTP (e.g., in a controller):

    use MustafaAwami\Lara2fa\Facades\Lara2fa;
    
    // Generate and display QR code for authenticator app
    $secret = Lara2fa::generateTotpSecret();
    $qrCodeUrl = Lara2fa::getTotpQrCodeUrl($user->email, $secret);
    
    return view('2fa.setup', compact('qrCodeUrl', 'secret'));
    
    // Verify user input
    $valid = Lara2fa::verifyTotpCode($secret, $userInputCode);
    if ($valid) {
        Lara2fa::enableTotp($user);
    }
    

Implementation Patterns

Core Workflows

1. TOTP (Authenticator App)

  • Setup:
    // Generate secret and QR code
    $secret = Lara2fa::generateTotpSecret();
    $qrCodeUrl = Lara2fa::getTotpQrCodeUrl($user->email, $secret);
    
    // Store secret temporarily (e.g., in session)
    session(['two_factor_secret' => $secret]);
    
    // Verify user input
    $valid = Lara2fa::verifyTotpCode($secret, $userInputCode);
    if ($valid) {
        Lara2fa::enableTotp($user); // Saves to DB
    }
    
  • Login Check:
    if (Lara2fa::isTotpEnabled($user)) {
        $code = request('two_factor_code');
        if (!Lara2fa::verifyTotpCode($user->two_factor_secret, $code)) {
            return back()->withErrors(['two_factor_code' => 'Invalid code.']);
        }
    }
    

2. Email OTP

  • Send OTP:
    $otp = Lara2fa::generateEmailOtp($user->email);
    Lara2fa::sendEmailOtp($user->email, $otp); // Uses Laravel Mail
    
  • Verify OTP:
    $valid = Lara2fa::verifyEmailOtp($user->email, $userInputCode);
    

3. Passkeys (WebAuthn)

  • Registration:
    $challenge = Lara2fa::createPasskeyChallenge();
    return view('passkey.register', compact('challenge'));
    
    // Handle credential creation
    $credential = Lara2fa::finishPasskeyRegistration(
        $challenge,
        request()->all(),
        $user->email
    );
    
  • Authentication:
    $challenge = Lara2fa::createPasskeyChallenge();
    return view('passkey.login', compact('challenge'));
    
    $verified = Lara2fa::verifyPasskey(
        $challenge,
        request()->all(),
        $user->passkey_credentials
    );
    

4. Recovery Codes

  • Generate/Display:
    $codes = Lara2fa::generateRecoveryCodes($user);
    return view('2fa.recovery', compact('codes'));
    
  • Verify:
    $valid = Lara2fa::verifyRecoveryCode($user, $userInputCode);
    if ($valid) {
        Lara2fa::consumeRecoveryCode($user, $userInputCode);
    }
    

Integration Tips

  1. Middleware for 2FA Checks: Create a middleware to enforce 2FA during login:

    // app/Http/Middleware/CheckTwoFactor.php
    public function handle(Request $request, Closure $next) {
        if (auth()->check() && Lara2fa::isTwoFactorEnabled(auth()->user())) {
            if (!$request->session()->has('two_factor_verified')) {
                return redirect()->route('two.factor.verify');
            }
        }
        return $next($request);
    }
    
  2. Fallback Logic: Combine methods for resilience:

    if (Lara2fa::isTotpEnabled($user)) {
        if (!Lara2fa::verifyTotpCode($user->two_factor_secret, $code)) {
            // Fallback to recovery codes
            if (!Lara2fa::verifyRecoveryCode($user, $code)) {
                return back()->withErrors(['code' => 'Invalid TOTP or recovery code.']);
            }
        }
    }
    
  3. Rate Limiting: Use Laravel’s throttling for OTP attempts:

    Route::middleware(['throttle:5,1'])->post('/verify-otp', ...);
    
  4. Customizing Emails: Extend the MustafaAwami\Lara2fa\Mail\OtpEmail class to modify OTP email templates.

  5. Passkey UI: Use the webauthn JavaScript library to handle credential creation/verification in the frontend:

    // Example for registration
    const credential = await navigator.credentials.create({
        publicKey: JSON.parse(@json($challenge)),
    });
    

Gotchas and Tips

Pitfalls

  1. Session Management:

    • Issue: TOTP secrets stored in session may cause issues if the session expires during setup.
    • Fix: Use a temporary database record or encrypted storage for secrets during setup.
  2. Passkey Browser Support:

    • Issue: WebAuthn (Passkeys) requires HTTPS and modern browsers (Chrome, Edge, Safari 15.4+).
    • Fix: Gracefully degrade for unsupported browsers:
      if (!Lara2fa::isWebAuthnSupported()) {
          return view('fallback-2fa');
      }
      
  3. Recovery Code Expiry:

    • Issue: Default expiry (e.g., 30 days) may not suit all use cases.
    • Fix: Override in config:
      'recovery_codes' => [
          'expiry_days' => 90,
      ],
      
  4. TOTP Secret Storage:

    • Issue: two_factor_secret is stored in plaintext in the DB.
    • Fix: Encrypt the secret before saving (customize the enableTotp method).
  5. Email OTP Collisions:

    • Issue: Race conditions if multiple OTPs are generated for the same email.
    • Fix: Use a unique token per request (e.g., session()->put('otp_token', Str::random(40))).

Debugging

  1. TOTP Verification Failures:

    • Ensure the timeStep (default: 30 seconds) matches the authenticator app’s settings.
    • Use Lara2fa::getTotpCurrentCode($secret) to debug expected codes.
  2. Passkey Errors:

    • Check the challenge and origin in the WebAuthn response match the server-side values.
    • Log JSON.stringify(publicKeyCredential) for debugging.
  3. OTP Not Received:

    • Verify the mail driver is configured (config/mail.php).
    • Check spam folders or use a test email service (e.g., Mailtrap).

Extension Points

  1. Custom OTP Generators: Override the OTP generator for non-numeric codes:

    Lara2fa::extend('otp', function ($email) {
        return Str::random(8); // Alphanumeric OTP
    });
    
  2. Multi-Factor Policies: Combine methods dynamically:

    Lara2fa::extend('policy', function ($user) {
        return [
            'required' => ['totp', 'recovery_codes'],
            'fallback' => ['email_otp'],
        ];
    });
    
  3. Event Listeners: Listen for 2FA events (e.g., TwoFactorEnabled):

    // app/Providers/EventServiceProvider.php
    protected $listen = [
        \MustafaAw
    
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