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

Google2Fa Laravel Package

pragmarx/google2fa

Google2FA adds HOTP/TOTP two-factor authentication to PHP, compatible with Google Authenticator and RFC 4226/6238. Generate secrets and QR code data, verify one-time codes, and tune validation windows and time drift—ideal for Laravel or standalone apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by installing the package via Composer: composer require pragmarx/google2fa. Then instantiate the Google2FA class directly or resolve it from the Laravel service container if using the Laravel bridge (pragmarx/google2fa-laravel). Your first use case is generating a secret key for a user, typically during onboarding for 2FA:

$secret = $google2fa->generateSecretKey(); // 32 chars by default in v9+
$user->google2fa_secret = $secret;
$user->save();

Next, generate a QR code URL for the user to scan into their authenticator app:

$qrUrl = $google2fa->getQRCodeUrl('MyApp', 'support@myapp.com', $secret);
// Use any QR library (e.g., SimpleQrCode, Endroid\QrCode) to render it  

Finally, verify the OTP during login:

$valid = $google2fa->verifyKey($user->google2fa_secret, $request->input('otp'));

Begin with the README’s usage section and the playground to see live OTP behavior.

Implementation Patterns

Use dependency injection for Google2FA in Laravel to access methods cleanly. Common workflow patterns:

  • Onboarding flow:
    • Generate secret → store in DB → generate QR → user scans → confirm (e.g., by entering a one-time code from their app).
    • Use verifyKey() during confirmation, not just initial scan.
  • Login flow:
    • After password validation, present OTP input → call verifyKey() or verifyKeyNewer() to prevent reuse.
    • Store last verified timestamp ($user->google2fa_ts) for verifyKeyNewer().
  • QR generation: Pair with a dedicated QR library (e.g., simplesoftwareio/simple-qrcode) and leverage getQRCodeUrl() to create a standards-compliant otpauth:// URI.
  • Bulk setup / testing: Use setWindow() to relax time sensitivity during development or in distributed environments:
    $google2fa->setWindow(4); // Accept keys valid for 4×30s intervals (2 min past/future)
    
  • Algorithm flexibility: For compliance (e.g., FIPS 140-2), switch to SHA256 or SHA512:
    $google2fa->setAlgorithm(Constants::SHA256);
    

Gotchas and Tips

  • Secret key length (v9+ breaking change): Default is now 32 chars (160-bit entropy). Ensure DB column (e.g., google2fa_secret) can store at least 32 chars—older apps often used 16-char keys. To migrate: php artisan make:migration --table=users "modify google2fa_secret to varchar(64)". Existing 16-char secrets remain valid, but new ones default to 32.
  • Time sync matters: Inconsistent server time causes 2FA failures. Use NTP (ntpd -gq on Linux). Without sync, users may get “invalid code” even when correct.
  • Prevent replay attacks: Prefer verifyKeyNewer() over verifyKey(). Track the last valid timestamp per user (google2fa_ts) and reject older or duplicate entries.
  • QR code pitfalls: The getQRCodeUrl() returns a URL-encoded OTP URI. Never manually URL-encode it again. Pass it directly to your QR generator.
  • Testing: Use Carbon::setTestNow() to simulate time-critical OTP checks. Mock Google2FA and inject deterministic secrets during tests.
  • Validation window misconfiguration: Default window=1 allows ±30s window (i.e., key valid for up to 90s). For strict security, reduce to 0 and enforce user prompt speed. For user convenience (e.g., slow networks), increase to 3–4.
  • Prefixing secrets: Prefixing (e.g., with user_id) is possible but tricky—prefix must be Base32-safe and padding-respecting (lengths like 1,2,5,10,20…). Use cautiously:
    $secret = $google2fa->generateSecretKey(16, str_pad($userId, 10, 'X'));
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport