47

I'm manually creating users programmatically, and I want to sign in the newly created user. WP makes it easy to access the hashed password, but not the plaintext version. Is there a way to use wp_signon() without the plaintext password?

I found one person who claims to have done this here, but it didn't work for me.

THANKS!

1
  • I think you can just assign the user object of the user you just created to the current_user global variable May 28, 2012 at 13:27

6 Answers 6

42

wp_set_auth_cookie() will log a user in without having to know their password.

4
  • This worked great. However, when I use it, the conditional is_user_logged_in() doesn't seem to work. Do you know if it's looking at something different than the cookies? May 28, 2012 at 13:44
  • 2
    @Emerson - what hook are you logging them in on? it has to be before headers are sent. also try to wp_set_current_user before logging them in.
    – Milo
    May 28, 2012 at 13:47
  • I actually wasn't calling it from a hook at all. I just added wp_set_auth_cookie() into my signin function. I guess I need to rethink that. I'll also lookup wp_set_current_user and report back. Thank you very much for your help on this! May 28, 2012 at 13:59
  • Well, is it possible to login a user without having his details exist in database? Just setting few cookies in browser through script is enough? Please let me know. Feb 6, 2014 at 9:10
63

The following code does the job for automatic login, without any password!

// Automatic login //
$username = "Admin";
$user = get_user_by('login', $username );

// Redirect URL //
if ( !is_wp_error( $user ) )
{
    wp_clear_auth_cookie();
    wp_set_current_user ( $user->ID );
    wp_set_auth_cookie  ( $user->ID );

    $redirect_to = user_admin_url();
    wp_safe_redirect( $redirect_to );
    exit();
}
4
  • Well, it works great. Just the username is enough, which is case insensitive. Feb 6, 2014 at 7:50
  • 3
    get_user_by() returns false on failure, so you should check for false instead of the WP_Error object Apr 14, 2016 at 20:41
  • @Sjoerd Linders, where can I hook your script in order to force a user to be connected?
    – RafaSashi
    Aug 31, 2016 at 16:45
  • Where do I keep this block of code in which file?
    – sgiri
    May 28, 2019 at 7:32
15

I have found another solution here that uses a better approach (at least in my opinion...). No need to set any cookie, it uses the Wordpress API:

/**
 * Programmatically logs a user in
 * 
 * @param string $username
 * @return bool True if the login was successful; false if it wasn't
 */
    function programmatic_login( $username ) {
        if ( is_user_logged_in() ) {
            wp_logout();
        }

    add_filter( 'authenticate', 'allow_programmatic_login', 10, 3 );    // hook in earlier than other callbacks to short-circuit them
    $user = wp_signon( array( 'user_login' => $username ) );
    remove_filter( 'authenticate', 'allow_programmatic_login', 10, 3 );

    if ( is_a( $user, 'WP_User' ) ) {
        wp_set_current_user( $user->ID, $user->user_login );

        if ( is_user_logged_in() ) {
            return true;
        }
    }

    return false;
 }

 /**
  * An 'authenticate' filter callback that authenticates the user using only     the username.
  *
  * To avoid potential security vulnerabilities, this should only be used in     the context of a programmatic login,
  * and unhooked immediately after it fires.
  * 
  * @param WP_User $user
  * @param string $username
  * @param string $password
  * @return bool|WP_User a WP_User object if the username matched an existing user, or false if it didn't
  */
 function allow_programmatic_login( $user, $username, $password ) {
    return get_user_by( 'login', $username );
 }

I think the code is self explanatory:

The filter searches for the WP_User object for the given username and returns it. A call to the function wp_set_current_user with the WP_User object returned by wp_signon, a check with the function is_user_logged_in to make sure your are logged in, and that's it!

A nice and clean piece of code in my opinion!

5
  • where to use programmatic_login?
    – RafaSashi
    Aug 31, 2016 at 16:50
  • Perfect answer!
    – Maximus
    Jul 8, 2017 at 23:05
  • @Shebo Your comment doesn't seem to be correct. The first line of the function checks whether the array $credentials is empty or not. If the array is not empty (which is the case in my answer), the values from the array are used to authenticate the user.
    – Mike
    Sep 4, 2017 at 9:17
  • @Mike wow, how do I missed it... My bad, sorry for misleading. I'll delete my first comment, to avoid confusion. Great solution though :)
    – Shebo
    Sep 4, 2017 at 11:49
  • It might be worthwhile to enclose wp_signon() in a try block and call remove_filter in the finally block. This should ensure that the filter is always removed.
    – Leukipp
    Jul 23, 2020 at 3:35
8

This works well for me:

  clean_user_cache($user->ID);
  wp_clear_auth_cookie();
  wp_set_current_user($user->ID);
  wp_set_auth_cookie($user->ID, true, false);
  update_user_caches($user);
1
3

In addition to Mike, Paul and Sjoerd:

To better handle login.php redirections:

//---------------------Automatic login--------------------

if(!is_user_logged_in()){

    $username = "user1";

    if($user=get_user_by('login',$username)){

        clean_user_cache($user->ID);

        wp_clear_auth_cookie();
        wp_set_current_user( $user->ID );
        wp_set_auth_cookie( $user->ID , true, false);

        update_user_caches($user);

        if(is_user_logged_in()){

            $redirect_to = user_admin_url();
            wp_safe_redirect( $redirect_to );
            exit;
        }
    }
}
elseif('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] == wp_login_url()){

    $redirect_to = user_admin_url();
    wp_safe_redirect( $redirect_to );
    exit;
}

To be placed in wp-config.php just after

require_once(ABSPATH . 'wp-settings.php');

FYI

Based on the above solution, I have released a plugin to keep the user logged in from one wordpress to another by synchronizing user data and cookie session:

https://wordpress.org/plugins/user-session-synchronizer/

1

Strange enough but the only way it works for me is if I redirect and die() after:

clean_user_cache($user->ID);
wp_clear_auth_cookie();
wp_set_current_user( $user_id, $user->user_login );
wp_set_auth_cookie( $user_id, true, true );
update_user_caches( $user );

if ( is_user_logged_in() ) {

    $redirect_to = $_SERVER['REQUEST_URI'];
    header("location:".$redirect_to );
    die(); 

}
1
  • 2
    You can set the $redirect_to var to any existing page in you site. Eg: $redirect_to = site_url(); Feb 25, 2021 at 17:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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