3

I'm trying to login a user via the REST API, and then retrieve the current user on subsequent requests. As per the documentation, in my plugin, I am creating and retrieving a nonce after a successful login. The nonce is returned correctly, but every REST call results in a wp_create_nonce() call which resets the nonce, this is followed by another call to it with action = heartbeat-nonce call, which resets it again and then wp_create_nonce() is called again which resets it back. So after I login the user the nonce has changed.

Now when I make my next API call, the same thing happens again. This is results in any nonce I send with my API request invalid and current-user is set to 0 and thus my logged in user is never valid.

I tried creating a new nonce for every request, but the multiple calls to create_nonce, 3 every request, keeps resetting the nonce. I am logging calls to wp_create_nonce and I can see that even when I make no API calls, this function is called every 2 mins on it's own.

I am still working my way through the WordPress development, so please excuse any ignorance. I would really appreciate some help here as I can't seem to move past this point.

EDIT: Apologies for being unclear. I am working on a React front-end delivering WordPress content via the REST API. I am trying to authenticate a user, and then allow them to create a post. The user is an Author. To achieve this I made a plugin, that provides me routes to login, and then submit a post if the user is authorized.

register_rest_route($this->namespace, '/auth/login', array(
    'methods' => WP_REST_Server::CREATABLE,
    'callback' => array($this, 'reactpress_jwt_auth_user_signin'),
  ));

This eventually leads to the below function being called.

public static function reactpress_jwt_user_login($user_obj){

//Login user with wp_signon()
$credentials = array(
  'user_login' => $user_obj['username'],
  'user_password' => $user_obj['password'],
  'remember' => false
);

$user = wp_signon( $credentials, false );

if(!is_wp_error($user)){

  //Set the current user
  $current_user = wp_set_current_user($user->data->ID);

  //This calls wp_create_nonce('wp_rest');
  $nonce_val = self::reactpress_jwt_generate_nonce(); 

  $response = array(
    'user' => $current_user->data->user_nicename,
    'nonce' => $nonce_val
  );

  return $response;

}else{
  return new WP_Error('reactpress-jwt-auth-fail', 'User signin failed ' . $user->message);
}
}

Now when I make a second call to the API, I'm setting _wpnonce as this returned nonce value. But it never matches because the nonce value is regenerated by the 3 calls to wp_create_nonce(). I'm using Postman to send my requests.

I logged calls to wp_create_nonce and below is a sample from by debug.log, of the function being called automatically from somewhere, i.e. not after an explicit call to the REST API by me.

[16-Dec-2018 19:07:23 UTC] INSIDE CREATE NONCE wp_rest
[16-Dec-2018 19:07:23 UTC] CURRENT USER ID IS 1
[16-Dec-2018 19:07:23 UTC] GENERATED NONCE IS  8d7dd8f044
[16-Dec-2018 19:07:23 UTC] INSIDE CREATE NONCE heartbeat-nonce
[16-Dec-2018 19:07:23 UTC] CURRENT USER ID IS 1
[16-Dec-2018 19:07:23 UTC] GENERATED NONCE IS  c719f185fc
[16-Dec-2018 19:07:23 UTC] INSIDE CREATE NONCE updates
[16-Dec-2018 19:07:23 UTC] CURRENT USER ID IS 1
[16-Dec-2018 19:07:23 UTC] GENERATED NONCE IS  c1701a5519
[16-Dec-2018 19:07:23 UTC] INSIDE CREATE NONCE wp_rest
[16-Dec-2018 19:07:23 UTC] CURRENT USER ID IS 1
[16-Dec-2018 19:07:23 UTC] GENERATED NONCE IS  8d7dd8f044
[16-Dec-2018 19:07:23 UTC] Inside VERIFY NONCE c719f185fc
[16-Dec-2018 19:07:23 UTC] CURRENT USER ID  1
[16-Dec-2018 19:07:23 UTC] nonce generated 0-12 hours ago

The user I logged in has User id 2. I am logged into the backend via my Admin user, with User ID 1. Could that be what is causing this?

EDIT: No, logging in as Admin is not the cause. I tried again without logging into the backend. Received a nonce after logged in and placed a request.

[17-Dec-2018 06:59:37 UTC] INSIDE REST COOKIE CHECK ERRORS
[17-Dec-2018 06:59:37 UTC] _wpnonce is set 67c6049b8b
[17-Dec-2018 06:59:37 UTC] Inside VERIFY NONCE 67c6049b8b
[17-Dec-2018 06:59:37 UTC] CURRENT USER ID  2
[17-Dec-2018 06:59:37 UTC] nonce NOT generated 0-12 hours ago expected it to be --> add87a8b0b
[17-Dec-2018 06:59:37 UTC] nonce NOT generated 12-24 hours ago expected it to be --> 5523ad082e

67c6049b8b is the nonce I received after login, and which I sent with my second API call, which returned:

{
 "code": "rest_cookie_invalid_nonce",
 "message": "Cookie nonce is invalid",
 "data": {
    "status": 403
 }
}
  • 1
    Please consider editing your question and adding the bare bones code that will reproduce the issue. – Dave Romsey Dec 16 '18 at 21:08
  • 2
    Nonces don't have state, and aren't stored, they're time based, so there's nothing to "reset" as such. I would expect that wp_create_nonce be called on every non-REST page request at a minimum so that JS knows what the nonce to send with the request is. Are you sure this isn't an issue with setting cookies or cookies expiring? Especially with what you said about current user being set to 0, that implies there's some important contextual things you're not telling us. What exactly are you trying to implement? ( describe it from a non-technical standpoint ) – Tom J Nowell Dec 16 '18 at 21:08
  • Sorry for not being clearer. I have added more details about my app, as well as code from my plugin. Please let me know if more information is required. – monologish Dec 17 '18 at 6:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.