I am currently working on a multi-steps registration system, based on the new Wordpress Rest API and I got an issue related to the nonce generation and verifying.
My first step is to ask the user from a frontend form for the essential information (name - firstname - email address). The second one is to ask him for additional metadata information. Then the third one to ask him for its password and password confirmation.
There are 3 different HTTP Post request in the process, everything is handled in AJAX. The strategy I applied is to generate a nonce on the server side if the first POST is ok, and to return it in the JSON response. Here is the code for the user creation at the first step:
$user_id = wp_insert_user( $userdata ) ;
$user = new \WP_User($user_id);
if (!empty( $user ) && $user instanceof \WP_User) {
$user->add_role( 'subscriber' );
}
// Autologin after registration
wp_set_current_user($user_id);
wp_set_auth_cookie($user_id);
// Storing the regitration event for the user
$this->saveLoginEvent( $user_id );
$data = array(
'user_id' => $user_id,
'nonce' => wp_create_nonce( 'wp_rest' ),
'message' => 'user_created'
);
The user is properly created and logged-in. But, using this nonce during the additional steps is considered invalid (always getting 403). My code for veryfying the nonce is the following:
/**
* authenticate_call - Default permission callback used to validate that the call is coming from our frontend
*
* @return {WP_nonce} The state of the nonce, if it is verified or not
*/
public function authenticate_call() {
if ( isset( $_REQUEST['_wpnonce'] ) ) {
$nonce = $_REQUEST['_wpnonce'];
} elseif ( isset( $_SERVER['HTTP_X_WP_NONCE'] ) ) {
$nonce = $_SERVER['HTTP_X_WP_NONCE'];
}
if ( empty( $nonce ) || null === $nonce ) {
// No nonce at all, so act as if it's an unauthenticated request.
return new \WP_Error( 'rest_cookie_no_nonce', __( 'Nonce is invalid' ), array( 'status' => 403 ) );
}
$result = wp_verify_nonce( $nonce, 'wp_rest' );
if ( ! $result ) {
return new \WP_Error( 'rest_cookie_invalid_nonce', __( 'Cookie nonce is invalid' ), array( 'status' => 403 ) );
}
return true;
}
The error I am getting is the second one: rest_cookie_invalid_nonce
. The nonce is passed as URL parameter like this POST www/api/url?_wpnonce=a30e88f0bd
. Any idea ? Do you know anything about an impossibility to have the backend generating the nonce and returning it to the frontend ? Should I generate it on the frontend using a method I don't know about yet. If it helps, I am using Timber and Twig as the frontend architecture components.
Thanks in advance,
$data
array in the first code block'nonce' => wp_create_nonce( 'wp_rest' ),