chillerlan/php-authenticator
PHP 8.4+ library to generate and validate HOTP (RFC 4226) and TOTP (RFC 6238) one-time passwords—Google Authenticator compatible. Includes Steam Guard server time sync (cURL) and constant-time encoding/hex helpers (Sodium or fallback).
digits, period), allowing flexibility for future requirements.AuthManager, Guard) via constructor injection.otpauth:// URI generation, which can be rendered as QR codes using Laravel’s Dingo/api or spatie/qr-code packages.Attempting, Authenticated) to enforce 2FA flows.^5.4) or upgrade PHP.ext-sodium for secure encoding. Fallback to paragonie/constant_time_encoding is provided but adds minor complexity.Carbon can be used to ensure consistency.Encrypter can help here.sessions or users table). Laravel’s migrations can handle this.±1 code) needed?Carbon can freeze time for testing.Auth facade or custom guards (e.g., Auth::attempt() → trigger 2FA).Attempting, Authenticated, or Failed events to inject 2FA logic.spatie/qr-code to render otpauth:// URIs.otp_secret (string) and otp_counter (integer, for HOTP) to the users table.Schema::table('users', function (Blueprint $table) {
$table->string('otp_secret')->nullable();
$table->integer('otp_counter')->default(0);
});
composer require chillerlan/php-authenticator
2fa column to the users table (see above).2fa middleware to check for enabled 2FA and prompt for OTP.AuthManager or create a custom TwoFactorGuard:
use chillerlan\Authenticator\Authenticator;
use chillerlan\Authenticator\AuthenticatorOptions;
class TwoFactorGuard extends Guard {
protected function authenticateUsingCredentials(array $credentials) {
// ... existing logic ...
if ($this->has2FA($user)) {
$otp = $this->getOTPInput(); // From request
$authenticator = new Authenticator(
new AuthenticatorOptions(['digits' => 6]),
$user->otp_secret
);
if (!$authenticator->verify($otp)) {
throw new AuthenticationException;
}
}
}
}
AuthServiceProvider:
$this->app['guard'] = function ($app) {
return new TwoFactorGuard(...);
};
otp_secret).use chillerlan\Authenticator\Authenticator;
use SimpleSoftwareIO\QrCode\Facades\QrCode;
$authenticator = new Authenticator();
$secret = $authenticator->createSecret();
$uri = $authenticator->getUri('User Email', 'App Name');
return QrCode::size(200)->generate($uri);
^5.4 of the package.ext-curl (optional, for Steam Guard time sync).ext-sodium (recommended; fallback provided).otp_secret/otp_counter.Authenticator (mock time/counters).rotate2FASecret() method in a Laravel command/service to regenerate secrets periodically.$authenticator = new Authenticator();
$newSecret = $authenticator->createSecret();
$user->update(['otp_secret' => $newSecret]);
backup_codes JSON column to the users table for manual recovery.getServertime() to debug.digits, algorithm, and period settings match the authenticator app (e.g., Google Authenticator).How can I help you explore Laravel packages today?