Weave 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 Google Authenticator Laravel Package

scheb/2fa-google-authenticator

Adds Google Authenticator-based two-factor authentication (TOTP) to Symfony apps. Generates QR codes and secrets, validates one-time codes, and plugs into your login flow to improve account security with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require scheb/2fa-google-authenticator
    

    Ensure scheb/2fa-bundle is also installed (this package extends it).

  2. Configuration: Add the bundle to config/bundles.php:

    Scheb\TwoFactorBundle\SchebTwoFactorBundle::class => ['all' => true],
    
  3. Enable in Security: In config/packages/security.yaml, add:

    firewalls:
        main:
            form_login:
                provider: app_user_provider
            two_factor: ~  # Enables 2FA
    
  4. First Use Case:

    • Generate a secret key for a user:
      use Scheb\TwoFactorBundle\Generator\GoogleAuthenticatorGenerator;
      
      $generator = new GoogleAuthenticatorGenerator();
      $secret = $generator->generateSecret();
      
    • Store the secret in your user model (e.g., user.two_factor_secret).
    • Display a QR code for the user to scan (use Scheb\TwoFactorBundle\Generator\GoogleAuthenticatorGenerator::getQRCodeImageAsDataUri()).

Implementation Patterns

Workflows

  1. User Onboarding:

    • Generate a secret during registration or profile setup.
    • Store the secret in the database (encrypted if sensitive).
    • Render a QR code for the user to scan via Google Authenticator:
      <img src="{{ app.user.two_factor_qr_code }}" alt="QR Code">
      
    • Prompt the user to enter a verification code to confirm setup.
  2. Login Flow:

    • After successful password authentication, redirect to the 2FA form:
      # config/routes.yaml
      two_factor_login:
          path: /login-2fa
          controller: Scheb\TwoFactorBundle\Controller\TwoFactorController::checkCode
      
    • Validate the code using the bundle’s TwoFactorValidator:
      $validator = $this->container->get('scheb_two_factor.validator');
      if (!$validator->validateCode($user, $code)) {
          // Handle failure (e.g., retry or fallback).
      }
      
  3. Fallback Mechanisms:

    • Implement a "backup code" system or email-based fallback for lost devices.
    • Use the bundle’s TwoFactorAuthenticatorInterface to customize fallback logic.
  4. API Integration:

    • For API endpoints, use the TwoFactorGuard to protect routes:
      use Symfony\Component\HttpFoundation\Request;
      use Scheb\TwoFactorBundle\Security\TwoFactorGuard;
      
      $guard = $this->container->get('security.guard.two_factor');
      if (!$guard->checkCode($user, $request->request->get('code'))) {
          throw new \RuntimeException('Invalid 2FA code');
      }
      

Integration Tips

  • Database Schema: Add a two_factor_secret column to your users table (e.g., VARCHAR(32) for Base32 secrets). Example migration:

    Schema::table('users', function (Blueprint $table) {
        $table->string('two_factor_secret')->nullable()->after('password');
    });
    
  • User Interface: Use the bundle’s Twig helpers to display QR codes and forms:

    {{ scheb_two_factor_qr_code(user.two_factor_secret) }}
    {{ scheb_two_factor_form(user) }}
    
  • Testing: Mock the GoogleAuthenticatorGenerator and TwoFactorValidator in unit tests:

    $validator = $this->createMock(TwoFactorValidator::class);
    $validator->method('validateCode')->willReturn(true);
    $this->container->set('scheb_two_factor.validator', $validator);
    

Gotchas and Tips

Pitfalls

  1. Secret Storage:

    • Never store secrets in plaintext. Encrypt the two_factor_secret in the database if your application handles sensitive data.
    • Avoid logging or exposing secrets in error messages.
  2. Time Synchronization:

    • Google Authenticator uses time-based codes (TOTP). Ensure your server’s time is synchronized (e.g., via NTP) to avoid validation failures.
    • Debugging tip: Use Scheb\TwoFactorBundle\Generator\GoogleAuthenticatorGenerator::checkCode() to manually verify codes during development.
  3. Session Management:

    • The bundle relies on Symfony’s session system. If using stateless APIs (e.g., JWT), implement custom session handling or use a hybrid approach (e.g., session + JWT).
  4. Rate Limiting:

    • Implement rate limiting on 2FA attempts to prevent brute-force attacks. Example with Symfony’s RateLimiter:
      # config/packages/security.yaml
      firewalls:
          main:
              two_factor:
                  rate_limiter: 'authentication.two_factor'
      services:
          authentication.two_factor:
              class: Symfony\Component\Security\Http\RateLimiter\RateLimiter
              arguments:
                  - '@security.http_utils'
                  - 5    # Max attempts
                  - 60   # Time window (seconds)
      
  5. Backup Codes:

    • The bundle does not include backup codes by default. Implement a custom solution using TwoFactorAuthenticatorInterface or a separate table for backup codes.

Debugging

  • Invalid Codes:

    • Verify the user’s two_factor_secret is correctly stored and not corrupted.
    • Check server time drift with:
      $generator = new GoogleAuthenticatorGenerator();
      $generator->checkCode($user->two_factor_secret, $code);
      
    • Enable debug mode in the bundle:
      # config/packages/scheb_two_factor.yaml
      scheb_two_factor:
          debug: true
      
  • QR Code Issues:

    • Ensure the secret is Base32-encoded. Use:
      $secret = rtrim(strtr(base64_encode(random_bytes(10)), '+/', '-_'), '=');
      
    • Test QR generation with:
      $generator = new GoogleAuthenticatorGenerator();
      $qrCodeUrl = $generator->getQRCodeImageAsDataUri('[email protected]', $secret);
      

Extension Points

  1. Custom Authenticators: Extend Scheb\TwoFactorBundle\Security\TwoFactorAuthenticator\TwoFactorAuthenticatorInterface to support additional providers (e.g., Authy, YubiKey).

  2. Event Listeners: Listen to scheb_two_factor.on_code_verified or scheb_two_factor.on_code_failed to trigger custom logic (e.g., logging, notifications):

    use Scheb\TwoFactorBundle\Event\TwoFactorEvent;
    
    $dispatcher->addListener(TwoFactorEvent::CODE_VERIFIED, function (TwoFactorEvent $event) {
        // Log successful 2FA.
    });
    
  3. Configuration Overrides: Override default settings in config/packages/scheb_two_factor.yaml:

    scheb_two_factor:
        google_authenticator:
            window: 1       # Allow 1 code window (default: 1)
            issuer: 'MyApp' # Custom issuer name for QR code
    
  4. CSRF Protection: Ensure 2FA forms include CSRF tokens. The bundle auto-generates tokens for Twig forms, but manually rendered forms require:

    {{ form_start(form, { 'attr': {'novalidate': 'novalidate'} }) }}
    {{ form_widget(form._token) }}
    
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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator