Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

After searching for a couple of days and reading 2 year old threads I'm having difficulty finding a solution to the problem of having users login by email only.

At first I was delighted to see WP_Email_Login only to find out you can still use your username to login. I'm not sure how to go about writing this as a plugin. My idea is to override the register_new_user function. I didn't see this on the "pluggable" functions list. Can I use filters/action do accomplish this?

I realize it's not fashionable to edit the core files so I'm hoping a solution is out there however if one does not exist I'll take my chances. In the first line of the "register_new_user" function in wp-login.php I can add:

$nickname_variable(??) = $user_login // set the nickname to the username
$user_login = $user_email; // set the user_login/username to the email address

This works quite nicely since WordPress doesn't allow people to change their username. In the Register Screen (form) it asks for the Username & Email; I'd like to set the Username to the Nickname variable (if someone can tell me what the nickname variable is called or where it's set during registration that'd be appreciated).

Cheers,

Smith

share|improve this question
    
Are you trying to do away with usernames entirely? Why won't the Email Login plugin work for you? –  Ryan May 9 '12 at 22:40
    
I'm really curious why you'd want to do away with usernames, since those are the basis of all user information in WordPress. It's a bit like trying to do away with Posts - a lot of work for not a lot of payoff, and a guarantee of issues down the road. –  SickHippie May 9 '12 at 23:00
    
@Ryan- I don't think I'll be able to get rid of usernames so instead I'm just forcing the username to equal the email address. –  agentsmith666 May 10 '12 at 6:29
    
@SickHippie - for login I think email is better and more unique than a username. I'd rather use the username as the nickname when the user posts. You're right it would be a pain to get "rid" of the variable "username" which is why I am not. I'm just choosing the username for the user when they register (username will be their email address; their nickname will be what they entered as their username). In the end no variables are lost everything is intact. –  agentsmith666 May 10 '12 at 6:34
1  
@SickHippie - You're right since Wordpress's default is not to allow user's to change their username their username/email address would remain the same even if they were to change their contact email address. I've considered that from the beginning and in my own experience I have found that people rarely "delete" an email address. They may get new ones but typically they'll still have their old ones. And if not perhaps in those rare circumstances we'll manually change it in the database. I do really appreciate your feedback & insight SickHippie! Now I hope for a solution to my post :) –  agentsmith666 May 13 '12 at 6:43
show 1 more comment

3 Answers

It's possible, you must change the filter for the name.

// remove the default filter
remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
// add custom filter
add_filter( 'authenticate', 'fb_authenticate_username_password', 20, 3 );
function fb_authenticate_username_password( $user, $username, $password ) {

    // If an email address is entered in the username box, 
    // then look up the matching username and authenticate as per normal, using that.
    if ( ! empty( $username ) )
        $user = get_user_by( 'email', $username );

    if ( isset( $user->user_login, $user ) )
        $username = $user->user_login;

    // using the username found when looking up via email
    return wp_authenticate_username_password( NULL, $username, $password );
}

An alternative is an plugin, there you find via Google oder in the plugin repo; maybe this plugin.

share|improve this answer
    
Thanks for the reply however I'm not sure if you read my post or if I wasn't clear enough. I apologize for the latter. In my original post I mentioned WP_Email_Login plugin; the exact plugin your code and link is from. Here's my original post: "At first I was delighted to see WP_Email_Login only to find out you can still use your username to login." <--- See the problem I can still use a username so that's why this plugin will not work. Since I can't do away with usernames I'm thinking of overriding the register function by forcing the username to equal the email address. –  agentsmith666 May 10 '12 at 6:37
    
However I'm searching for a way to accomplish this without editing the core files. If it's not possible that's fine but I'd like to know either way. Thanks! –  agentsmith666 May 10 '12 at 6:41
    
this is a way without editing the core files. Copy the code in a plugin, activate and ready. –  bueltge Apr 1 '13 at 22:06
add comment

Using the above code:

// Change login credentials
// remove the default filter
remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
// add custom filter
add_filter( 'authenticate', 'my_authenticate_username_password', 20, 3 );
function my_authenticate_username_password( $user, $username, $password ) {

    // If an email address is entered in the username box, 
    // then look up the matching username and authenticate as per normal, using that.
    if ( ! empty( $username ) ) {
        //if the username doesn't contain a @ set username to blank string
        //causes authenticate to fail
        if(strpos($username, '@') == FALSE){
                $username = '';
            }
        $user = get_user_by( 'email', $username );
        }
    if ( isset( $user->user_login, $user ) )
        $username = $user->user_login;

    // using the username found when looking up via email
    return wp_authenticate_username_password( NULL, $username, $password );
} 

All we had to do was check that the provided username at-least looked like a email and if not sabotage the username.

share|improve this answer
add comment

Slight modifications to the code above should be all that is needed to create an elegant solution. The documentation for the authenticate hook states that either a WP_User object or WP_Error object should be returned.

The source code for the wp_authenticate_username_password function runs through some pretty simple checks; we can just replicate the way those checks are done, and create a new WP_Error object to deal with the email address. Alternatively, we could even jack the wp_authenticate_username_password code and modify it if we wanted, although that seems unnecessary unless you really want to customize how things function. The code below should do the trick: (Although I haven't tested it myself...)

// Remove the default authentication function
remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );

// Add the custom authentication function
add_filter( 'authenticate', 'custom_authenticate_username_password', 20, 3 );

function custom_authenticate_username_password( $user, $username, $password ) {

    // Get the WP_User object based on the email address
    if ( ! empty( $username ) ) {
        $user = get_user_by( 'email', $username );
    }

    // Return a customized WP_Error object if a WP_User object was not be returned (i.e. The email doesn't exist or a regular username was provided)
    if ( ! $user ) {
        return new WP_Error( 'invalid_username_email', sprintf( __( '<strong>ERROR</strong>: Invalid username. Please log in with your email address. <a href="%s" title="Password Lost and Found">Lost your password</a>?' ), wp_lostpassword_url() ) );
    }

    // Hand authentication back over to the default handler now that we a have a valid WP_User object based on the email address
    return wp_authenticate_username_password( null, $username, $password );
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.