Extend WordPress (4.x) session and nonce

We’ve got a small web application that allows users to log in (via WordPress) and remain logged in for a max 15 min session for security purposes. Because most sessions will last longer, I have a small ajax call that’s made on each click of the html document itself.

The ajax call itself fires to the /admin-ajax.php file, and it hits a function (in functions.php). Below is that function:

function extend_my_session_yo(){
    $user_id = get_current_user_id();
    wp_set_auth_cookie($user_id, false, true);

    $new_logout = wp_logout_url();

    if ( is_user_logged_in() ) {
        echo 'session extended 15 mins ' . $new_logout;
    } 
    // if a user is *not* logged in, WordPress just outputs a "0". 
    die();
}

The wp_set_auth_cookie() does the hard work. It correctly allows for (on each click) an extended 15 mins session. The problem is if someone tries to logout. The current logout link is echo’d via wp_logout_url(), but that logout url has a nonce from the moment it’s created by WordPress.

So in the function above, I’m generating a new logout url (and from the WP core code it seems that this is generated by getting the session token from the new cookie), but each click of the new logout url gives the WordPress Failure Notice page indicating a nonce mismatch. I’ve even gone so far to copy code from pluggable.php (for wp_verify_nonce()) for checking the hash_equals() function for $expected vs $nonce and they’re equal. Yet I still get nonce errors.

Does anyone know how to set a new auth/logged_in cookie while also setting a new nonce to avoid these errors?

1
1

Your problem is that you call wp_logout_url immediately after wp_set_auth_cookie.

wp_set_auth_cookie() does some setcookie() calls. Unfortunately setcookie doesn’t make the new value available instantly in the PHP global $_COOKIE. It must be set through a new HTTP Request first.

wp_logout_url() (via wp_nonce_url > wp_create_nonce > wp_get_session_token > wp_parse_auth_cookie) fetches $_COOKIE[LOGGED_IN_COOKIE] in order to create a valid nonce, not knowing that the logged in cookie has already been updated. (I’m not quite sure if we may call this a WP core bug.)

There is an action hook in wp_set_auth_cookie named set_logged_in_cookie, which should allow you to update the session cookie value during your ajax request.

function my_update_cookie( $logged_in_cookie ){
    $_COOKIE[LOGGED_IN_COOKIE] = $logged_in_cookie;
}
add_action( 'set_logged_in_cookie', 'my_update_cookie' );

Leave a Comment