I know that the REST API is a huge topic of conversation in WordPress right now, and rightfully so, but there are still times in which we have to use admin-ajax (as its coming to be known) for a variety of reasons.

  • Perhaps it’s an application,
  • Perhaps time doesn’t allow for creating the necessary endpoints,
  • Perhaps you’re more comfortable with admin-ajax,
  • And so on.

Regardless of your reasons for why you use it (which I still do, for whatever that’s work), I think it’s important to make sure we’re sending secure Ajax requests in WordPress using nonces just as you would if you were submitting traditional form data.

Secure Ajax Requests in WordPress

Legitimate, live shot of wires carrying your Ajax request.

If you search the web for results on how to do that, you’ll come up with a variety of answers, and this will be just another drop in the proverbial bucket.

But if you’re curious for a recipe for how to handle it, this is how I do it each time.

Secure Ajax Requests in WordPress

The process for sending secure Ajax requests for WordPress follows this procure:

  1. enqueue your JavaScript file and use  wp_localize_script,
  2. ensure your JavaScript is sending the security nonce,
  3. check the security value in your call back and handle it appropriately.

With that said, here are a few gists for each of the above that will hopefully lead you to write more secure Ajax-based code.

1. Enqueue JavaScript, Localize Your Script

I know this seems like a weird first step considering you should write it before you enqueue it. And you should, of course. But for this post, I wanted to show the necessary code before jumping into the details.

There are some ways in which people opt to enqueue admin-ajax.php, but this is the process that I follow for both enqueueing my file and adding admin-ajax.php:

Notice in the code above, the call to wp_enqueue_script looks exactly like you would expect.

But wp_localize_script is a little different. Here’s what it’s doing:

  1. It follows the call to enqueue script (and the order matters),
  2. it uses the same identifier, namely acme-security,
  3. It defines an object that we can use in our JavaScript code called acme_ajax_object and defines two properties.
  4. The ajax_url property maintains the path to admin-ajax.php.
  5. The security property maintains a value returned by wp_create_nonce.

So how do we leverage all of this within the context of our JavaScript?

2. Using This Information in JavaScript

First, when making an Ajax call, we need to make sure that we’re using the ajax_url property of the object we defined in the code above. That is, the request’s URL should be sent to acme_ajax_object.ajax_url.

You then define the function that you want to call. In this case, it’s get_custom_date which we’ll look into in a moment.

But the most important part comes next: We then make sure to send a security value which is maintained by the security property of acme_ajax_object.

Notice that in the response function, we check to make sure that the response has a success properly, handle it appropriately, and then move forward with our code.

So what does the server-side code look like for this?

3. Verifying The Security

Next, in your callback function (which we’ve appropriately named get_custom_data we need to first check the security value before doing anything else.

If the value passes, we’re good to go; otherwise, we need to send an error.

Notice that when we call check_ajax_referer, we use the key of the value defined in wp_create_nonce and the name of the property of the object we defined in the first step.

If it doesn’t check out, we send a JSON error that we can read in the JavaScript as we saw above. This should always be the first step before doing actual work.

If all checks out, we’re good to go.

Is This Really Secure?

This is the inevitable question, isn’t it? To be fair, I don’t want to promise this is completely foolproof because I’m not a security expert.

But having a nonce value that will leverage WordPress’ built-in security functions is better than blindly sending data with no way to verify the source of what’s being sent.

Naturally, you also need to sanitize the data before interrogating it, using it, potentially saving it, and so on. But that’s the content for a different post.

This, instead, provides a recipe for making sure you’re sending secure Ajax requests in WordPress.