I really don’t understand what is happening with WordPress nonces, i think they’re wrong, or they’re useless.
I always have troubles working with that nonces, WordPess never been able to check one nonce successfully, i will put here 2 cases in which the nonces aren’t working, in all cases i tried to maken aj AJAX request:
CASE 1:
In this case i tried to use wp_rest nonce to verify it:
PHP (plugin.php):
<?php
require("ajax_endpoints.php");
class MyPluginClass {
public static function setup_plugin() {
add_shortcode("my_shortcode", array(self::class, "my_shortcode_func"));
}
public my_shortcode_func() {
// Only add scripts when this shotcode is used
self::add_plugin_scripts();
wp_enqueue_script("my_script", plugin_url("js/myscript.js", __FILE__), [], "1.0");
wp_localize_script("my_script", "script_data", array(
"endpoint_url" => rest_url("/my/rest"),
"endpoint_url2" => rest_url("/my/rest2"),
"nonce" => wp_create_nonce("wp_rest")
));
}
}
MyPluginClass::setup_plugin();
?>
JS:
$.ajax({
url: script_data.endpoint_url,
data: [], // Here is some real data
type: "post",
dataType: "json",
headers: {
'X-WP-Nonce': script_data.nonce
},
success: () => { ... },
error: () => { ... }
});
It only works when the user is logged in, but i’m not using users on my website, the only user is admin, so, it doesn’t work for guests users (And i need to works for them), when is a guest user, it returns: rest_cookie_invalid_nonce 403 error
PD. I don’t put the code of the ajax functions ’cause it doesn’t even get to run them
CASE 2
So i don’t want to put more code here, but, for this case, in wp_create_nonce
function i change the wp_rest
string for any_value
string
In the $.ajax call y delete the headers
option, and y pass the nonce in the data
option as "nonce_field", and in my rest functions i do this:
var_dump(check_ajax_referer("any_value", "nonce_field"));
And it always returns false, the nonce never pass, and also happens with:
var_dump(wp_verify_nonce($_POST["nonce_field"], "any_value"));
So the nonce never is true, and i don’t know why, it should be an WordPress issue, i’m using WordPress 5.5 (The most recent version) so i think if it’s always return false then the nonce in WordPress are useless
Or can you help me what i’m doing wrong? Thanks a lot!!!
2
Answers
Use wp_verify_nonce( $_POST["nonce_field"], "wp_rest" ); for verify nonce.
When you take a look at the
wp_verify_nonce
function in wp-includes/pluggable.php, you’ll see that it is a user based validation. But in your case you want to make it public and in this case there is no need for nonces. Just tell WordPress the route is to be public by adding'permission_callback' => '__return_true'
into the args array when creating your custom route via theregister_rest_route
function:Then just remove the x-wp-nonce header from the ajax function:
WordPress checks the nonce automatically (by running the
wp_verify_nonce
function against the "wp_rest" action name) when you add anX-WP-Nonce
header to your ajax request or a "_wpnonce" key to your POST/GET arguments/parameters.