PHP code example of coding-libs / laravel-mfa

1. Go to this page and download the library: Download coding-libs/laravel-mfa library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

coding-libs / laravel-mfa example snippets


use CodingLibs\MFA\Facades\MFA;

// Email/SMS - Generate and send automatically
$challenge = MFA::issueChallenge(auth()->user(), 'email');
// then later
$ok = MFA::verifyChallenge(auth()->user(), 'email', '123456');

// Generate challenge without sending
$challenge = MFA::generateChallenge(auth()->user(), 'email');
// or
$challenge = MFA::issueChallenge(auth()->user(), 'email', false);
// Now handle sending manually

// TOTP
$setup = MFA::setupTotp(auth()->user());
// $setup['otpauth_url'] -> QR code; then verify
$ok = MFA::verifyTotp(auth()->user(), '123456');

// Generate QR code (base64 PNG) from existing TOTP (uses bacon/bacon-qr-code)
$base64 = MFA::generateTotpQrCodeBase64(auth()->user(), issuer: 'MyApp');
// <img src="$base64" />

// Remember device (set cookie on successful MFA)
[$token, $cookie] = [null, null];
$result = MFA::rememberDevice(auth()->user(), lifetimeDays: 30, deviceName: 'My Laptop');
$token = $result['token'];
$cookie = $result['cookie']; // Symfony Cookie instance — attach to response

// Later, skip MFA if remembered device cookie is valid
$shouldSkip = MFA::shouldSkipVerification(auth()->user(), MFA::getRememberTokenFromRequest(request()));

// Recovery Codes
// Generate a fresh set (returns plaintext codes to show once)
$codes = MFA::generateRecoveryCodes(auth()->user());
// Verify and consume a recovery code
$ok = MFA::verifyRecoveryCode(auth()->user(), $inputCode);
// Count remaining unused codes
$remaining = MFA::getRemainingRecoveryCodesCount(auth()->user());
// Clear all codes
$deleted = MFA::clearRecoveryCodes(auth()->user());

// Generate N codes (defaults come from config)
$codes = MFA::generateRecoveryCodes($user); // array of plaintext codes

// Show these codes once to the user and prompt them to store securely
// e.g., render as a list and offer a download/print option

if (MFA::verifyRecoveryCode($user, $input)) {
    // Success: log user in and consider rotating codes if desired
}

// Count remaining unused codes
$remaining = MFA::getRemainingRecoveryCodesCount($user);

// Replace all existing codes with a new set
$fresh = MFA::generateRecoveryCodes($user); // replaceExisting=true by default

// Append without deleting existing codes
$extra = MFA::generateRecoveryCodes($user, count: 2, replaceExisting: false);

// Clear all codes
$deleted = MFA::clearRecoveryCodes($user);

// config/mfa.php
'email' => [
    'enabled' => true,
    'channel' => \App\Channels\CustomEmailChannel::class,
    'from_address' => '[email protected]',
    // ... other config
],

'sms' => [
    'enabled' => true,
    'channel' => \App\Channels\CustomSmsChannel::class,
    'driver' => 'custom',
    // ... other config
],

// app/Channels/CustomEmailChannel.php
use CodingLibs\MFA\Channels\EmailChannel;

class CustomEmailChannel extends EmailChannel
{
    public function send(Authenticatable $user, string $code, array $options = []): void
    {
        // Custom sending logic
        Mail::to($user->email)->send(new CustomMfaMail($code, $this->config));
    }
}

// In a service provider
MFA::registerChannelFromConfig('custom_channel', [
    'channel' => CustomChannel::class,
    'channel_name' => 'custom_channel',
    'custom_setting' => 'value'
]);

// Generate challenge without sending
$challenge = MFA::generateChallenge(auth()->user(), 'email');
echo $challenge->code; // Use the code as needed

// Or use issueChallenge with send=false
$challenge = MFA::issueChallenge(auth()->user(), 'email', false);

// Manual sending
$channel = MFA::getChannel('email');
$channel->send(auth()->user(), $challenge->code, ['subject' => 'Custom Subject']);

use CodingLibs\MFA\Contracts\MfaChannel;
use CodingLibs\MFA\Facades\MFA;
use Illuminate\Contracts\Auth\Authenticatable;

class WhatsAppChannel implements MfaChannel {
    public function __construct(private array $config = []) {}
    public function getName(): string { return 'whatsapp'; }
    public function send(Authenticatable $user, string $code, array $options = []): void {
        // send via provider...
    }
}

// register at boot
MFA::registerChannel(new WhatsAppChannel(config('mfa.whatsapp', [])));

// then issue
MFA::issueChallenge(auth()->user(), 'whatsapp');

php artisan vendor:publish --tag=mfa-config
php artisan vendor:publish --tag=mfa-migrations
php artisan migrate