Using WordPress ‘authenticate’ PHP filter

The authenticate WordPress PHP filter filters whether a set of user login credentials are valid. A WP_User object is returned if the credentials authenticate a user, and WP_Error or null otherwise.

Usage

add_filter('authenticate', 'your_custom_function', 10, 3);
function your_custom_function($user, $username, $password) {
    // your custom code here
    return $user;
}

Parameters

  • $user: null | WP_User | WP_Error – WP_User if the user is authenticated. WP_Error or null otherwise.
  • $username: string – Username or email address.
  • $password: string – User password.

More information

See WordPress Developer Resources: authenticate

Examples

Prevent login with an email address

Disallow users from logging in with their email address:

add_filter('authenticate', 'prevent_email_login', 10, 3);
function prevent_email_login($user, $username, $password) {
    if (is_email($username)) {
        return new WP_Error('email_login_disabled', 'Login with email address is disabled.');
    }
    return $user;
}

Block specific usernames

Block users with certain usernames from logging in:

add_filter('authenticate', 'block_specific_usernames', 10, 3);
function block_specific_usernames($user, $username, $password) {
    $blocked_usernames = ['admin', 'test'];

    if (in_array($username, $blocked_usernames)) {
        return new WP_Error('username_blocked', 'This username is not allowed.');
    }
    return $user;
}

Require a minimum password length

Require users to have a minimum password length to log in:

add_filter('authenticate', 'require_min_password_length', 10, 3);
function require_min_password_length($user, $username, $password) {
    if (strlen($password) < 8) {
        return new WP_Error('short_password', 'Password must be at least 8 characters long.');
    }
    return $user;
}

Check for a custom user meta value

Allow login only if the user has a specific custom meta value:

add_filter('authenticate', 'check_custom_user_meta', 10, 3);
function check_custom_user_meta($user, $username, $password) {
    if (is_a($user, 'WP_User')) {
        $approved = get_user_meta($user->ID, 'user_approved', true);
        if (!$approved) {
            return new WP_Error('user_not_approved', 'Your account is not approved yet.');
        }
    }
    return $user;
}

Limit login attempts

Limit the number of login attempts from a specific IP address:

add_filter('authenticate', 'limit_login_attempts', 10, 3);
function limit_login_attempts($user, $username, $password) {
    $ip = $_SERVER['REMOTE_ADDR'];
    $max_attempts = 5;
    $attempts = get_transient('login_attempts_' . $ip);

    if ($attempts >= $max_attempts) {
        return new WP_Error('login_attempts_exceeded', 'Too many failed login attempts. Please try again later.');
    }

    if (!is_a($user, 'WP_User')) {
        $attempts += 1;
        set_transient('login_attempts_' . $ip, $attempts, 60 * 60);
    } else {
        delete_transient('login_attempts_' . $ip);
}
return $user;
}

### 6. Require two-factor authentication
Require users to enter a one-time code sent to their email for two-factor authentication:

add_filter('authenticate', 'require_two_factor_authentication', 10, 3);
function require_two_factor_authentication($user, $username, $password) {
    if (is_a($user, 'WP_User')) {
        $otp = get_user_meta($user->ID, 'otp', true);
        if (empty($otp) || !isset($_POST['otp']) || $otp != $_POST['otp']) {
            return new WP_Error('invalid_otp', 'Invalid one-time code. Check your email for the correct code.');
        } else {
            delete_user_meta($user->ID, 'otp');
        }
    }
    return $user;
}

In this example, you would need to generate and send a one-time code (OTP) to the user’s email address before they can log in. You could use the wp_authenticate action hook to generate and send the OTP when a user attempts to log in.