Generating nonce through Javascript and logged in users 403
-
Hello,
I have a situation where I am attempting to combat nonces getting cached.
To help with this, I setup an endpoint like so:
function generate_nonce(WP_REST_Request $request) {
$nonce = wp_create_nonce('wp_rest');
$response = array(
'nonce' => $nonce
);
return rest_ensure_response($response);
}I am then calling this in Javascript to get a nonce, before trying to access another endpoint:
<script>
async function fetchNonce() {
try {
const response = await fetch('/wp-json/test/v1/nonce');
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
const data = await response.json();
console.log('Nonce:', data.nonce);
return data.nonce;
} catch (error) {
console.error('Error fetching nonce:', error);
return null;
}
}
async function fetchAllPosts(nonce) {
try {
const response = await fetch('/wp-json/test/v1/posts', {
method: 'GET',
headers: {
'X-WP-Nonce': nonce
}
});
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
const data = await response.json();
console.log('Posts:', data);
} catch (error) {
console.error('Error fetching posts:', error);
}
}
async function executeFetches() {
const nonce = await fetchNonce();
if (nonce) {
await fetchAllPosts(nonce);
} else {
console.error('Failed to fetch nonce.');
}
}
document.addEventListener('DOMContentLoaded', () => {
executeFetches();
});
</script>This is just to give an idea about the scenario. Getting all posts is just an example to demonstrate.
Anyway.
The test endpoints are like this:
add_action('rest_api_init', 'my_custom_endpoints');
function my_custom_endpoints() {
register_rest_route('test/v1', '/nonce', array(
'methods' => 'GET',
'callback' => 'generate_nonce',
'permission_callback' => '__return_true',
));
// Endpoint for getting all posts
register_rest_route('test/v1', '/posts', array(
'methods' => 'GET',
'callback' => 'get_all_posts',
'permission_callback' => '__return_true',
));
}This works all well and good for logged out user, as the nonce is valid as through some research it the wp_rest nonce uses user id by default for logged out user or some such?
But as soon as a logged in user tries to generate a nonce through the endpoint and Javascript, error 403 is given even though a nonce is passed and gets created. Real headache causing and frustrating.
Is there any direction this can be managed, or is it entirely a wrong direction?
Thank you. ????
Here is the get_all_posts as well if it provides some information:
function get_all_posts(WP_REST_Request $request) {
$nonce = $request->get_header('X-WP-Nonce');
if (!wp_verify_nonce($nonce, 'wp_rest')) {
return new WP_Error('rest_invalid_nonce', __('Invalid nonce'), array('status' => 403));
}
// Arguments for WP_Query to fetch all posts
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1, // Retrieve all posts
);
// Fetch the posts
$query = new WP_Query($args);
$posts = array();
// Check if there are posts
if ($query->have_posts()) {
// Loop through posts and prepare data
while ($query->have_posts()) {
$query->the_post();
$posts[] = array(
'id' => get_the_ID(),
'title' => get_the_title(),
'content' => get_the_content(),
'excerpt' => get_the_excerpt(),
'date' => get_the_date(),
'author' => get_the_author(),
'link' => get_permalink()
);
}
// Restore original Post Data
wp_reset_postdata();
}
// Return the response as JSON
return rest_ensure_response($posts);
}
- You must be logged in to reply to this topic.