I am struggling to implement nonces through XML request to php backend using the Wordpress nonce validation when creating forms dynamically. I am ok with the form built version

wp_nonce_field( 'delete-comment_'.$comment_id );

So I am trying to use the other nonce options when passing via javascript localization.

$nonce = wp_create_nonce( 'my-action_'.$post->ID ); 

Then to verify, there seems to be two options.

check_ajax_referer( 'process-comment' );
wp_verify_nonce( $_REQUEST['my_nonce'], 'process-comment'.$comment_id );

Both of which I seem unable to make recognised in the validation. There is a number being passed through the post, and I have tried, naming, not naming, and a lot of other options too, but seem unsuccessful to do something that is meant to be simple. The examples given on the codex are mightily confusing too.

eg: here https://codex.wordpress.org/WordPress_Nonces

Can anyone shed any light on this frustrating experience? Many Thanks

  • have you considered using a REST API endpoint instead? Why do you create a nonce with a post ID then process it with a comment ID? The nonce name has to be identical. Also why do you check for an ajax referrer that's missing the ID?
    – Tom J Nowell
    Nov 1, 2017 at 21:33
  • Ah, sorry, I was copying directly from the codex for the examples as a reference point. As you can see they are quite misleading. I was just wondering if that something is being missed out on the explanations here. Im sure I would be without issue if these were a little clearer through the examples. Nov 1, 2017 at 23:46

2 Answers 2


Okay, so I found a working solution which is as simple as I thought the whole process should be. The confusing Wordpress codex made things harder really.

The creation and naming of the nonce is as simple as:
wp_create_nonce( 'example' );

This is passed though AJAX and localisation of the script to the PHP.

Then during a $_POST verification; all that is needed is to pass the post name as the second parameter in the verification function. eg:
check_ajax_referer( 'example', 'nonce')

nonce is the name of the $_POST identifier eg:

Somehow it was really hard to understand this through the codex, and other examples found through the web. I hope this explanation can help someone else struggling with the codex and nonces.


The root problem is that none of your nonces match

  • You create a nonce for: 'delete-comment_'.$comment_id

  • Then you create a nonce for: 'my-action_'.$post->ID

  • Then you check the referrer for a completely different nonce: 'process-comment'

  • Followed by a verification check on the nonce itself using yet another unique nonce name: 'process-comment'.$comment_id

So clearly, since none of them match, the checks will not match either and reject the nonce value passed.

When you generate a nonce, you give it an action/name, and it generates a token from that. You then check the token against the action/name when processing a request to verify the user did indeed intend to do that action.

e.g. create a nonce for 'delete-comment_'.$comment_id that you can then send with a delete comment request. Then the handler can check if you intended to delete that comment. It can't do that if the action/name doesn't match.

A Further Note on Auth

Nonces are a method of verifying intention, but they are not a method of authentication. Always check the user is logged in, and that the user is actually capable of doing what you intended via the current_user_can function.

A nonce can tell you that the user did indeed click the delete comment button, it doesn't tell you if they're allowed to delete comments though

  • Yes, I haven't any problem with creating complex capability checks, the only issue I am having is that passing the nonce through ajax. Nov 1, 2017 at 23:48
  • Can you edit your question then to contain a self contained simplest example that replicates your issue? Anything you can do to make your question clearer and simpler would also be useful. E.g. nowhere in your question is there any JS or calls to AJAX handlers
    – Tom J Nowell
    Nov 2, 2017 at 0:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.