My understanding is that wordpress nonces (not exactly a "number used once") prevent cross-origin request forgery and last 12 hours.

I'm displaying a schedule of classes with a registration button for each class. I am re-using the nonce so that each button repeats the same nonce in a data attribute:

<button data-nonce="85bad21a61" data-event="unique-data">Unique</button>
<button data-nonce="85bad21a61" data-event="unique-data">Unique</button>

Users aren't logged in to wordpress. I'm storing their account data, returned from a successful API login, in a WP_Session variable.

Nonce is created with this line:

wp_create_nonce( 'register_for_an_event' )

And verified in a an ajax function here:

check_ajax_referer($_REQUEST['nonce'], "register_for_an_event", false);

I am logging some of the transactions to a text file and finding that different users are frequently submitting the same nonce, which seems natural as it's simply an html data attribute.

Is this a reasonable use of wp nonces?

The reason I'm concerned is that I'm told that intermittently a user will attempt to register for an event via the API, and instead, the previous user to register will be added to the event a second time.

Since users to not have WP accounts, I'm imagining that nonces are not the solution to this problem.

1 Answer 1


Nonces are not the way to solve your problem. You're using it correctly. I would look at the $wpdb->insert array you're probably using, and implement a check for data to exist that matches the proposed "new" entry.

I actually set up a Twilio SMS to fire off when weird validation errors are encountered. I have it text me a message and the database row id. I usually know about the problem while my client is still on their device having trouble. They think I'm magic when I text them and ask if they're having an issue.

  • I'm not adding anything to the database. Though it's possible I'll need to add some database logging just to figure out what's going on here–as you suggest, checking against previous entries. Thanks for the Twilio tip. I like it.
    – MikeiLL
    Commented Dec 12, 2018 at 2:46
  • would you make database entries of this nature in a custom table or in the options table?
    – MikeiLL
    Commented Dec 12, 2018 at 19:53
  • 1
    I have a custom test table with a few basic columns. Each function that writes/reports to it, I make sure it records its own name in the first column so I can go delete it after it ceases to be necessary. I find it convenient to keep hitting the refresh link on phpMyAdmin as a form of real time logging. I'm a little confused that you're writing nothing to the database during your transactions. You're picking up data from a session variable? Maybe the failure to pick up that variable from the user at hand is causing a recycle of the variable from the preceding user. ??
    – Elkrat
    Commented Dec 13, 2018 at 18:51
  • Yea it's an external API that my plugin interfaces with so at least up until now there's been no need to log anything to the database. I don't see how one user could be accessing a variable from another user's session, though.
    – MikeiLL
    Commented Dec 13, 2018 at 20:25
  • Either the plugin or the underlying Sessionz framework is misidentifying and then recalling the wrong session, which could be a manifestation of a race condition. But getting rid of sessions means you end up requiring a login. But you can do a "light login" by requiring a unique phone number or email. That's what I do. They click Submit and a custom post type Client is created for them. So no logins or password recoveries, but they are uniquely identified. They are literally a post with an id. You just save all their API data in metakeys.
    – Elkrat
    Commented Dec 14, 2018 at 0:17

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.