I want to login with username,email id and phone number in wordpress

I want to login in wordpress with username , email id and phone number.
where I am inserting phone number in User meta at the time of User registration.
Is there any hook where I can access user meta and validate it with password for login.
https://wordpress.org/plugins/wp-email-login/
I came to know that this plugin is used for username and email id validation at the login time. So, I can login with username and email id but my main issue was phone nmber which is in user meta table.

Related posts

4 comments

  1. Try this one :

    The first thing we need to do is remove the default authentication rights. Add the following snippet to your functions.php file:

    //remove wordpress authentication
    remove_filter('authenticate', 'wp_authenticate_username_password', 20);
    

    Next, we’re going to add our own authentication. To do so, we’re going to use add_filter.

    Add the following code to your functions.php files:

    add_filter('authenticate', function($user, $email, $password){
    
        //We shall SQL escape all inputs
        $user_phone = $wpdb->escape($_REQUEST['user_phone']);
        $password   = $wpdb->escape($_REQUEST['password']);
    
        //Check for empty fields
            if(empty($user_phone) || empty ($password)){        
                //create new error object and add errors to it.
                $error = new WP_Error();
    
                if(empty($user_phone)){ //No email
                    $error->add('empty_phone', __('<strong>ERROR</strong>: Phone field is empty.'));
                }
                if(empty($password)){ //No password
                    $error->add('empty_password', __('<strong>ERROR</strong>: Password field is empty.'));
                }
    
                return $error;
            }
    
            //Check if user exists in WordPress database
            //$user = get_user_by('email', $email);
            //Instead of the above one use this 
            $user = reset(
                         get_users(
                          array(
                           'meta_key' => 'user_phone',
                           'meta_value' => $user_phone,
                           'number' => 1,
                           'count_total' => false
                          )
                         )
                        );
    
            //bad email
            if(!$user){
                $error = new WP_Error();
                $error->add('invalid', __('<strong>ERROR</strong>: Either the phone or password you entered is invalid.'));
                return $error;
            }
            else{ //check password
                if(!wp_check_password($password, $user->user_pass, $user->ID)){ //bad password
                    $error = new WP_Error();
                    $error->add('invalid', __('<strong>ERROR</strong>: Either the phone or password you entered is invalid.'));
                    return $error;
                }else{
                    return $user; //passed
                }
            }
    }, 20, 3);
    

    Form this time should be :

    Ofcourse if you want one input field for all then it can be done. But you need to decide how will you choose which validation to be performed phonenumber , email address or Username

    <form id="login" name="form" action="<?php echo home_url(); ?>/login/" method="post">
            <input id="user_phone" type="text" placeholder="Phone Number" name="user_phone">
            <input id="password" type="password" placeholder="Password" name="password">
            <input id="submit" type="submit" name="submit" value="Submit">
    </form>
    
  2. This is not the preferred solutions as we need to create a custom
    login form for achieving this

    You need to create a template at front end to be displayed like this :

    <form id="login" name="form" action="<?php echo home_url(); ?>/login/" method="post">
            <input id="username" type="text" placeholder="Username" name="username">
            <input id="user_phone" type="text" placeholder="Phone Number" name="user_phone">
            <input id="password" type="password" placeholder="Password" name="password">
            <input id="submit" type="submit" name="submit" value="Submit">
    </form>
    

    Above that write this php code which will work on form

    I am getting the User ID of the user by its username and then getting User Phone in the user_meta table by User ID and then matching it with submitted user phone number.

    You can make changes in the below code for validating the phone number
    separately.

    I have assumed the meta_key and input type name both as “user_phone”

    if($_POST) {
    
        global $wpdb;
    
        //We shall SQL escape all inputs
        $user_phone = $wpdb->escape($_REQUEST['user_phone']);
        $username   = $wpdb->escape($_REQUEST['username']);
        $password   = $wpdb->escape($_REQUEST['password']);
        $remember   = $wpdb->escape($_REQUEST['rememberme']);
    
        $user = get_userdatabylogin($username);
    
    
        if($remember) $remember = "true";
        else $remember = "false";
    
        $login_data = array();
        $login_data['user_login'] = $username;
        $login_data['user_password'] = $password;
        $login_data['remember'] = $remember;
    
        //get user phone number from DB
        $org_phone = get_user_meta($user->ID , 'user_phone',1);
    
        $user_verify = wp_signon( $login_data, false ); 
    
        if ( is_wp_error($user_verify) && $org_phone == $user_phone) 
        {
           header("Location: " . home_url() . "/login/error/");
           // Note, I have created a page called "Error" that is a child of the login page to handle errors. This can be anything, but it seemed a good way to me to handle errors.
         } else {    
           echo "<script type='text/javascript'>window.location='". home_url() ."'</script>";
           exit();
         }
    
    } else {
    
        // No login details entered - you should probably add some more user feedback here, but this does the bare minimum
    
        echo "Invalid login details";
    
    }
    
  3. Assuming you store the phone number in user_phone meta field. You can use the below code that I use in one of my plugins “Actions Pack” which provides user registration and login facility for Elementor page builder.

    // Login through phone number
    add_filter( 'authenticate', function ( $user, $phone, $password ){
        if ( $user instanceof WP_User ) {
            return $user;
        }
    
        if ( empty( $phone ) || empty( $password ) ) {
            if ( is_wp_error( $user ) ) {
                return $user;
            }
    
            $error = new WP_Error();
    
            if ( empty( $phone ) ) {
                // Uses 'empty_username' for back-compat with wp_signon().
                $error->add( 'empty_username', __( '<strong>Error</strong>: The phone field is empty.', 'actions-pack' ) );
            }
    
            if ( empty( $password ) ) {
                $error->add( 'empty_password', __( '<strong>Error</strong>: The password field is empty.', 'actions-pack' ) );
            }
    
            return $error;
        }
    
        if ( ! ap_is_phone( $phone ) ) {
            return $user;
        }
    
        $user = get_users( [ 'meta_key' => 'user_phone', 'meta_value' => $phone, 'number' => 1, 'count_total' => false ] )[0];
    
        if ( ! $user ) {
            return new WP_Error(
                'invalid_phone',
                __( 'Unknown phone number. Check again or try your username.', 'actions-pack' )
            );
        }
    
        /** This filter is documented in wp-includes/user.php */
        $user = apply_filters( 'wp_authenticate_user', $user, $password );
    
    
        if ( is_wp_error( $user ) ) {
            return $user;
        }
    
        if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
            return new WP_Error(
                'incorrect_password',
                sprintf(
                /* translators: %s: Phone Number. */
                    __( '<strong>Error</strong>: The password you entered for the phone number %s is incorrect.', 'actions-pack' ),
                    '<strong>' . $phone . '</strong>'
                ) .
                ' <a href="' . wp_lostpassword_url() . '">' .
                __( 'Lost your password?' ) .
                '</a>'
            );
        }
    
        return $user;
    }, 20, 3 );
    

    Here is a phone number validity check function. It depends on how you receive your phone number. Is it with country calling code or not.

    /**
     * Checks if it is a valid phone number
     * @toDo Improvise validity check.
     * https://stackoverflow.com/questions/14894899/what-is-the-minimum-length-of-a-valid-international-phone-number
     */
    function ap_is_phone( $phone ){
    
        $phone = filter_var($phone, FILTER_SANITIZE_NUMBER_INT);
        $phone = str_replace("-", "", $phone);
    
        if (strlen($phone) < 10 || strlen($phone) > 14) {
            return false;
        }
    
        return $phone;
    }
    

Comments are closed.