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

Google Authenticator Laravel Package

sonata-project/google-authenticator

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require sonata-project/google-authenticator
    

    Add to composer.json if using Laravel’s autoloader:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Sonata\\GoogleAuthenticator\\": "vendor/sonata-project/google-authenticator/src/"
        }
    }
    

    Run composer dump-autoload.

  2. First Use Case Generate a secret key and QR code for a user:

    use Sonata\GoogleAuthenticator\GoogleAuthenticator;
    use Sonata\GoogleAuthenticator\GoogleQrUrl;
    
    $ga = new GoogleAuthenticator();
    $secret = $ga->generateSecret(); // e.g., "JBSWY3DPEHPK3PXP"
    $qrCodeUrl = GoogleQrUrl::generate('YourAppName', $secret, 'user@example.com');
    

    Display $qrCodeUrl in the Google Authenticator app or render it as a QR code in your view.


Implementation Patterns

Core Workflows

  1. User Onboarding

    • Generate a secret key and QR code during user registration or profile setup.
    • Store the secret in the database (e.g., users table):
      $user->google_auth_secret = $ga->generateSecret();
      $user->save();
      
    • Provide the QR code or manual entry key to the user.
  2. Verification Logic

    • Validate OTPs in login/2FA flows:
      $otp = $request->input('otp');
      $isValid = $ga->checkCode($user->google_auth_secret, $otp);
      
    • Use middleware to enforce 2FA:
      namespace App\Http\Middleware;
      use Closure;
      use Sonata\GoogleAuthenticator\GoogleAuthenticator;
      
      class VerifyTwoFactor
      {
          public function handle($request, Closure $next)
          {
              $ga = new GoogleAuthenticator();
              $otp = $request->input('otp');
              if (!$ga->checkCode($request->user()->google_auth_secret, $otp)) {
                  abort(403, 'Invalid OTP');
              }
              return $next($request);
          }
      }
      
  3. Recovery Codes

    • Generate and store recovery codes (not part of the package; implement manually):
      $recoveryCodes = str_split(strtoupper(bin2hex(random_bytes(16))));
      $user->recovery_codes = json_encode($recoveryCodes);
      $user->save();
      

Integration Tips

  • Laravel Service Provider Bind the authenticator to the container for dependency injection:

    public function register()
    {
        $this->app->singleton(GoogleAuthenticator::class, function () {
            return new GoogleAuthenticator();
        });
    }
    

    Inject via constructor:

    public function __construct(GoogleAuthenticator $ga) {
        $this->ga = $ga;
    }
    
  • Caching Secrets Cache the last valid OTP to prevent replay attacks (e.g., using Laravel’s cache):

    $cacheKey = "user_{$user->id}_otp";
    if ($ga->checkCode($user->google_auth_secret, $otp) && !$request->hasSession()) {
        Cache::put($cacheKey, $otp, now()->addMinutes(1));
    }
    
  • Rate Limiting Use Laravel’s throttling middleware to limit OTP attempts:

    Route::middleware(['throttle:5,1'])->group(function () {
        // OTP verification routes
    });
    

Gotchas and Tips

Pitfalls

  1. Time Synchronization

    • Google Authenticator uses the device’s time. Users must ensure their device time is accurate (within 30 seconds). Sync issues can cause false rejections.
    • Workaround: Add a manual entry option for users to input the current time offset.
  2. Secret Storage

    • Secrets must be stored securely (e.g., encrypted in the database). Avoid logging or exposing them.
    • Tip: Use Laravel’s encryption:
      $user->google_auth_secret = encrypt($ga->generateSecret());
      
  3. Deprecated Methods

    • The package is archived (last release in 2021). Avoid relying on undocumented features. Stick to:
      • generateSecret()
      • checkCode($secret, $code)
      • GoogleQrUrl::generate()
  4. OTP Length

    • Google Authenticator uses 6-digit codes by default. Ensure your UI reflects this (e.g., input length validation).

Debugging

  • Test Locally Use the Google Authenticator app or emulator to verify secrets before deployment. Example test secret: JBSWY3DPEHPK3PXP (generates predictable codes for testing).

  • Logging Log failed attempts to debug synchronization issues:

    if (!$ga->checkCode($secret, $otp)) {
        Log::warning("OTP failure for user {$user->id}. Secret: {$secret}, Code: {$otp}");
    }
    

Extension Points

  1. Custom Algorithms

    • Extend GoogleAuthenticator to support TOTP (Time-based OTP) with custom parameters:
      $ga = new GoogleAuthenticator();
      $ga->getCode($secret); // Default: 30s interval, 6 digits
      
    • Override the getCode() method to adjust intervals/digits.
  2. Multi-Factor UI

    • Combine with Laravel’s session or cookies to persist 2FA status:
      $request->session()->put('2fa_verified', true);
      
  3. Backup Codes

    • Implement a backup system for recovery (e.g., store 10 one-time codes in the DB). Clear them after use.

Config Quirks

  • No Built-in Config The package has no configuration file. All settings (e.g., time step) are hardcoded. Override via dependency injection or subclassing:
    class CustomAuthenticator extends GoogleAuthenticator
    {
        public function __construct($timeStep = 30, $window = 1, $digits = 6)
        {
            parent::__construct($timeStep, $window, $digits);
        }
    }
    
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui