How to check username/password without signing in the user

I’m writing a plugin that creates an API endpoint that validates username/password pairs.

I’m currently using wp_signon() to check whether the username/password combo works. This works fine when the credentials fail because it returns an error object. But when the credentials are good, it automatcially signs in that user, so my endpoint returns a whole page.

Read More

The codex currently doesn’t even mention the fact that it automatically logs in the user. It also doesn’t appear to accept a parameter to suppress that functionality. For my purposes I simple boolean would be fine.

UPDATE:
I had to choose one single answer, but there was a lot of useful info several of the other answers which I’ll try to summarize briefly here…

  1. There IS a function that does exactly what I was trying to do: wp_authenticate($username, $password) HOWEVER, it comes with one drawback. It will automatically set the login cookies which can create problems in a situation like mine. So be careful. This function is not currently in the codex.

  2. The best choice for what I’m doing is wp_authenticate_username_password($user, $username, $password) because it DOESN’T set the login cookies. This function is more documented, but the REALLY important detail that wasn’t in the codex is that you can pass NULL as the first parameter. This means you can effectively use it to do exactly like wp_authenticate() without worrying about the cookies getting screwed up. Read the documentation so you don’t get confused by the response. It returns a either a WP_User object or a WP_Error (not a boolean!).

Related posts

Leave a Reply

4 comments

  1. There is a function in the user.php of the core files called wp_authenticate_username_password that seems like what you’re looking for.

    If you want to avoid throwing in the $user object (you probably only have the username + password), then just throw null as 1st function argument in:

    $check = wp_authenticate_username_password( NULL, 'some_username', '#thepassw0rd' );
    

    You can then simply check the result with is_wp_error( $check ).

  2. Disclaimer: This answer should just show what’s going on behind the scenes and is not meant to be a real life example on how to do things.


    Backtrace

    wp_signon() calls wp_set_auth_cookie(), which then calls wp_generate_auth_cookie(). The result will be used inside setcookie() as 2nd argument.

    (Non-performant) fun with filters

    a.k.a. tricking WordPress the wrong way.

    You could then just jump into the 'auth_cookie'-filter inside wp_generate_auth_cookie() and simply set it to null or something else than the SECURE_AUTH_COOKIE or AUTH_COOKIE value. This will then leave you with a senseless cookie, that can’t log in.

  3. Use,

    and

    Explanation

    // get user by login via the supplied username (form input)
    $user = get_user_by('login', $username);
    
    //assign user ID based on user login name
    $user_id = $user->ID;
    
    // get user data by passing the assigned $user_id variable to get_userdata
    // which returns the user object and a host of user related info to access
    $user_data = get_userdata($user_id);
    
    
    // assign the username and password to variables
    $user_login = $user_data->user_login;
    $user_pass = $user_data->user_pass;
    
    // check the username/password against the submitted input values
    if ($user_login = $username && $user_pass = $password) {
    
    // do something...
    

    Notes

    • $username should validate true by default otherwise a user object would not have been returned if the $username supplied did not match one already existing in the database. Therefore the validation then hinges on the $password variable which stores the form input supplied by the user.

    • There might be a more efficient way for you to achieve this, either by shortening the existing code or by using other API functions.

    UPDATE

    Based upon the suggestion by fdsa you could in turn use wp_authenticate_username_password in this fashion,

    $auth = wp_authenticate_username_password($user, $username, $password);
    
    if (!$auth->user_login = $username && !$auth->user_pass = $password) {
    
    echo 'not authenticated';
    
    } else {
    
    echo 'authenticated';
    
    }
    

    But even better than that,

    $auth = wp_authenticate_username_password($user, $username, $password);
    
    if (is_wp_error($auth)) {
    
    echo 'not authenticated';
    
    } else {
    
    echo 'authenticated';
    
    }
    

    Really the credit/marked answer ought to be given to fdsa for the most efficient method by way of (sadly) undocumented WP core function.

    http://wpseek.com/wp_authenticate_username_password/

  4. “Ta-da”: wp_authenticate($username, $password)

    It’s not in the codex at all, but you can look it up on wpseek.

    It does exactly what it sounds like. Takes a username and plain text password and returns either a WP_User object or a WP_Error… and it DOESN’T log anyone in.

    One note of caution! The following will ALWAYS return true (because the function returns an object either way):

    $auth = ( wp_authenticate($username, $password) ) ? TRUE : FALSE;
    

    You’ll probably want to do something like this:

    $test_creds = wp_authenticate($username, $pass) ;
    $class = get_class($test_creds);
    $auth = ( $class == 'WP_User' ) ? TRUE : FALSE ;
    

    I hope this helps someone.