pragmarx/google2fa
Google2FA is a PHP implementation of Google Two-Factor Authentication, supporting HOTP (RFC 4226) and TOTP (RFC 6238). It lets you generate secret keys, QR codes, and verify one-time passwords from Google Authenticator and similar apps, with an optional Laravel bridge.
Architecture fit
new Google2FA()), which means it slots into a Laravel service container cleanly as a singleton binding with zero coupling to Eloquent, HTTP, or session state.bacon/bacon-qr-code, google2fa-qrcode, or endroid/simple-qrcode). That is a second dependency with its own maintenance posture and its own failure modes (Imagick/GD availability, renderer API changes between majors).google2fa-laravel) exists and provides config, facade, middleware, and a basic enrollment controller. For a Laravel stack this is the higher-leverage integration point, but it adds a second package to track and is maintained by the same single author.Integration feasibility
composer require pragmarx/google2fa plus a QR backend, a nullable encrypted column, a verify endpoint, and middleware. Realistically 3–8 engineering days for a hardened implementation (enrollment, verification, recovery codes, admin reset, rate limiting, audit logging, tests) versus hours for a naive one.generateSecretKey(), getQRCodeUrl(), verifyKey($secret, $code, $window), verifyKeyNewer().verifyKeyNewer() returns a timestamp that the caller must persist. Nothing in the package prevents the same valid code being accepted twice unless we wire that up.Technical risk
string('google2fa_secret', 16), any max:16 validation rule, any test asserting length 16, and any UI constrained to 16 characters will break or silently truncate on upgrade. Silent truncation of a secret is catastrophic — the user enrolls successfully and can never authenticate again.pragmarx/google2fa, historically renamed from the antonioribeiro GitHub org). Typosquat/namespace-confusion on auth libraries is a genuine supply-chain vector, and the metadata as given is not internally consistent.Key questions
TwoFactorProvider interface now.Stack fit
Google2FA::class as a container singleton; inject rather than instantiate so tests can mock verification.pragmarx/google2fa (pin ^9.0), one QR backend (bacon/bacon-qr-code), optionally pragmarx/google2fa-laravel for the middleware and config scaffolding. Pin exact minor versions in composer.lock and treat auth-path dependency updates as security-review-gated.google2fa_secret (encrypted cast, length ≥ 64 to absorb base32 32-char secrets plus ciphertext overhead), google2fa_enabled_at, google2fa_last_ts (for verifyKeyNewer replay protection), and a separate two_factor_recovery_codes table or encrypted JSON column.encrypted cast on the secret. Do not store base32 secrets in plaintext — database read access would otherwise equal full 2FA bypass.Migration path
Compatibility
ImagickImageBackEnd requires the Imagick extension; the GD/SVG backends are lighter. Validate in the container image, not just locally.otpauth:// URI emitted by getQRCodeUrl(). Provide a manual base32 entry fallback for users whose camera or app fails.Sequencing
enabled_at. Never mark enabled until the user proves possession.verifyKeyNewer + persisted timestamp) and per-user/per-IP throttling before any broad rollout.Maintenance
Support
Scaling
$window to 8 (as documented) expands accepted codes from 3 to 17 and meaningfully widens the brute-force surface — default to window 1 and only raise it in response to measured clock-drift complaints.Failure modes
Ramp-up
How can I help you explore Laravel packages today?