WordPress Two-Factor Authentication: Code vs Plugin Implementation

Two-factor authentication dramatically reduces the impact of stolen passwords on WordPress admin accounts. You can implement TOTP-based 2FA with a few lines of code using a PHP TOTP library, or integrate it cleanly via a battle-tested plugin — knowing both options lets you choose the right trade-off.

Problem: WordPress uses a single password for admin access with no second factor — a leaked or brute-forced password gives an attacker full control of the site immediately.

Solution: Add TOTP-based two-factor authentication: use the Two-Factor plugin for a no-code solution that adds an authenticator app flow to the standard login form, or implement it with a custom plugin using a TOTP library — generate a secret per user, display it as a QR code during setup, then verify the six-digit code on every login with authenticate and wp_authenticate_user hooks.

The examples below show how to enforce 2FA for specific user roles, generate and verify TOTP codes with the RobThree/TwoFactorAuth library, and configure the free Two-Factor plugin for admin-only enforcement.

createSecret();
update_user_meta( $user_id, '_2fa_secret', $secret );
update_user_meta( $user_id, '_2fa_enabled', false ); // not confirmed yet

// 2. Show QR code on the profile page
$qr_url = $tfa->getQRCodeImageAsDataUri( $user->user_login, $secret );
echo 'Scan with authenticator app';

// 3. Verify the code entered by the user (e.g., on a custom login step)
$code   = sanitize_text_field( $_POST['2fa_code'] ?? '' );
$secret = get_user_meta( $user_id, '_2fa_secret', true );
if ( $tfa->verifyCode( $secret, $code ) ) {
    update_user_meta( $user_id, '_2fa_enabled', true );
    // proceed with login
} else {
    wp_die( 'Invalid 2FA code' );
}

Enforce 2FA for admins using the free Two-Factor plugin (WordPress.org):

roles, true ) ) return;

    // Check if Two-Factor plugin is active
    if ( ! function_exists( 'Two_Factor_Core::is_user_using_two_factor' ) ) return;

    // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
    if ( ! Two_Factor_Core::is_user_using_two_factor( $user->ID ) ) {
        // Redirect to profile to set up 2FA before reaching admin
        wp_redirect( admin_url( 'profile.php#two-factor-options' ) );
        exit;
    }
}, 10, 2 );

// Force 2FA setup notice in the admin
add_action( 'admin_notices', function() {
    if ( ! current_user_can( 'administrator' ) ) return;
    if ( ! function_exists( 'Two_Factor_Core::is_user_using_two_factor' ) ) return;
    if ( Two_Factor_Core::is_user_using_two_factor( get_current_user_id() ) ) return;

    echo '

Security: ' . 'Two-factor authentication is required for administrator accounts. ' . 'Set up 2FA now.

'; } );

NOTE: For most sites, the Two-Factor plugin is the better choice — it handles backup codes, email fallback, and recovery. Custom TOTP code makes sense only when you need to integrate 2FA into a fully headless or non-standard login flow.

Leave Comment

Your email address will not be published. Required fields are marked *