Google Authenticator (2FA)

True\GoogleAuthenticator implements the standard TOTP (Time-based One-Time Password) algorithm — the same one Google Authenticator, Authy, and 1Password use — so you can layer 2FA over any existing login flow.

Generate a secret

Each user gets their own secret. Generate one when they enable 2FA and store it next to the user record:

$authenticator = new True\GoogleAuthenticator;
$secret = $authenticator->createSecret(); // default 16 chars (16–128)

Show a QR code

Hand the secret to an authenticator app by rendering a QR code. getQRCode() returns a URL pointing at a hosted QR image:

$qrCodeUrl = $authenticator->getQRCode(
    'test@example.com', // account name shown in the app
    $secret,
    'MyApp'             // optional issuer label
);
echo "<img src='$qrCodeUrl' alt='Scan with Google Authenticator'>";

Optional fourth arg accepts a ['width' => ..., 'height' => ..., 'level' => ...] array for size + error-correction level.

Verify a code

When the user enters a 6-digit code from the app, check it against the stored secret:

if ($authenticator->verifyCode($secret, $code)) {
    // proceed with login / sensitive action
} else {
    // reject — invalid or expired code
}

The default $discrepancy of 1 accepts codes from the previous and next 30-second windows, which absorbs minor clock drift between server and client.

Generate a code yourself

Useful for testing, or for backup flows that send the code via another channel:

$code = $authenticator->getCode($secret);

Code length

Default codes are 6 digits. Pass a different length if your client expects 7 or 8:

$authenticator->setCodeLength(8);

The method returns the instance, so you can chain it onto construction.

Where it fits in a login flow

Pair this with AuthenticationJWT: the first call to login() returns false when the user has 2FA enabled. Show them a code-entry form, validate with verifyCode(), then call updateToken() to finalize the session.