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.
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.
Use dependency injection for Google2FA in Laravel to access methods cleanly. Common workflow patterns:
verifyKey() during confirmation, not just initial scan.verifyKey() or verifyKeyNewer() to prevent reuse.$user->google2fa_ts) for verifyKeyNewer().simplesoftwareio/simple-qrcode) and leverage getQRCodeUrl() to create a standards-compliant otpauth:// URI.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)
$google2fa->setAlgorithm(Constants::SHA256);
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.ntpd -gq on Linux). Without sync, users may get “invalid code” even when correct.verifyKeyNewer() over verifyKey(). Track the last valid timestamp per user (google2fa_ts) and reject older or duplicate entries.getQRCodeUrl() returns a URL-encoded OTP URI. Never manually URL-encode it again. Pass it directly to your QR generator.Carbon::setTestNow() to simulate time-critical OTP checks. Mock Google2FA and inject deterministic secrets during tests.0 and enforce user prompt speed. For user convenience (e.g., slow networks), increase to 3–4.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'));
How can I help you explore Laravel packages today?