I have a headless install of Wordpress on v5.4.0
. The frontend can't GET any post that is in draft
status, though when accessing the API url directly the data is returned without an issue. I'm assuming this is cookie/auth related. Note, I'm dynamically grabbing the nonce
values from the backend, showing full strings here for the sake of argument. Here's my setup and screenshots of the responses:
Request URL: http://wordpress.test/wp-json/wp/v2/pages/19060?wpnonce=23c01b3b12&_embed=true
Called on the frontend using isomorphic-unfetch
(also tried with axios
) like so:
fetch("http://wordpress.test/wp-json/wp/v2/pages/19060?wpnonce=23c01b3b12&_embed=true", {
credentials: "include"
})
Here's the request/response from the frontend, which is not working (this does work for all published
content):
With this body:
{
"code":"rest_forbidden",
"message":"Sorry, you are not allowed to do that.",
"data":{
"status":401
}
}
When trying to access the data directly, I see two different responses depending on the wpnonce
query parameter underscore:
This works (using _wpnonce
) returning the proper JSON data:
http://wordpress.test/wp-json/wp/v2/pages/19060?_wpnonce=23c01b3b12&_embed=true
Details:
This does not (using wpnonce
):
http://wordpress.test/wp-json/wp/v2/pages/19060?wpnonce=23c01b3b12&_embed=true
Details:
Returns the same response error that the frontend does:
{
"code":"rest_forbidden",
"message":"Sorry, you are not allowed to do that.",
"data":{
"status":401
}
}
EDIT:
I've also tried the X-WP-Nonce
header mentioned here (https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/) and it doesn't seem to be recognized:
fetch(postUrl, {
credentials: "include",
headers: {
"X-WP-Nonce": wpnonce
}
})
{"code":"rest_cookie_invalid_nonce","message":"Cookie nonce is invalid","data":{"status":403}}
EDIT 2:
On a clean install of WP and a new barebones frontend (html + jquery) I'm seeing the same issue. However, I find that the nonce is valid when generating the preview link, but invalid when WP tries to verify using rest_cookie_check_errors
. How can the same nonce with the same action (wp_rest
) fail verification?:
I'm seeing that wp_get_session_token()
is failing because there's no cookie found on REST requests. (https://core.trac.wordpress.org/browser/tags/5.4/src/wp-includes/pluggable.php#L2140) Isn't the point of the nonce
to not require cookies? Could it be an issue with cross-domain cookie paths?
I am sending credentials in the XHR. Here's my frontend test code:
// GET page with Nonce header
$.ajax({
url: postUrl,
method: "GET",
xhrFields: {
withCredentials: true
},
beforeSend: function(xhr) {
xhr.setRequestHeader("X-WP-Nonce", wpnonce);
xhr.setRequestHeader("Content-Type", "application/json");
}
})
Two questions:
- Mainly, how can I get draft post data using nonce values from the frontend?
- Why in the world would the
_wpnonce
/wpnonce
query vars show different results on the frontend and backend?
credentials: 'include'
infetch()
).