Restricting user login by IP address

IP address validation during authentication – for a selected user only

Here’s a way to hook into the authenticate filter and validate the IP address for a given user during authentication.

The user can see the invalid IP address error like shown here:

invalid IP address

/**
 * Validate IP Address During Authentication - For A Given User 
 */
add_filter( 'authenticate', function( $user )
{
    // Adjust to your needs:
    $allowed_user_ip        = '127.0.0.1';
    $ip_restricted_user_id  = 1;

    // Current user's IP address
    $current_user_ip = isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : null;

    // Nothing to do for valid IP address
    if( $current_user_ip === $allowed_user_ip )
        return $user;

    // Nothing to do for users that are not IP restricted 
    if( 
           $user instanceof \WP_User 
        && $user->ID > 0
        && $ip_restricted_user_id != $user->ID
    )   
        return $user;

    // Add an 'Invalid IP address' error
    if( is_wp_error( $user ) )
        $user->add( 
            'invalid_ip', 
            sprintf(
            '<strong>%s</strong>: %s',
            esc_html__( 'ERROR', 'mydomain' ),
            esc_html__( 'IP address is invalid.', 'mydomain' )
        )
    ); 
    // Create a new 'Invalid IP address' error
    else
        $user = new WP_Error(
            'invalid_ip', 
            sprintf(
                '<strong>%s</strong>: %s',
                esc_html__( 'ERROR', 'mydomain' ),
                esc_html__( 'IP address is invalid.', 'mydomain' )
            )
        ); 

    return $user;
}, 100 );

Here we use the priority of 100 because of these default callbacks:

add_filter( 'authenticate', 'wp_authenticate_username_password',  20, 3 );
add_filter( 'authenticate', 'wp_authenticate_email_password',     20, 3 );
add_filter( 'authenticate', 'wp_authenticate_spam_check',         99    );

It should be possible to extend this to handle a group of users or a given user role.