Cookie-based authentication when using the WordPress API Fetch NPM package

A nice little side effect of the development of WordPress’ Gutenberg block editor is that we now have a range of WordPress-oriented NPM packages available to us.

One such package that I’ve been using in recent development for the ACF Custom Database Tables plugin is the @wordpress/api-fetch package which, as its name implies, is all about fetching data from API’s.

When making requests to a public API, we can just go ahead use it without any need for authentication. The simplest example of this goes a little like this:

import apiFetch from "@wordpress/api-fetch";
apiFetch({
path: '/wp-json/some/endpoint',
}).then((data) => {
// use data here
});

If a resource requires the user to have certain permissions, however, we need to send some information along with the request so WordPress can authenticate the user and check they have the correct permissions.

Whilst developing the upcoming field value migration feature, I’ve decided to move in the direction of a React-based UI that leverages the WordPress REST API and, as you might expect, these API endpoints need to be restricted to users with certain permissions — we wouldn’t want anyone kicking off migrations that modify a website’s data from a public API!

Fortunately, WordPress’ REST API has baked in support for cookie-based authentication and will do it all for us if we provide the X-WP-Nonce request header, the value of which needs to be a nonce created using the 'wp_rest' action. e.g; wp_create_nonce('wp_rest').

Looking at the REST API Handbook, we can see examples of how to set this header on an XHR object.

How to set the X-WP-Nonce header when using @wordpress/api-fetch

When using the @wordpress/api-fetch package, things are a touch different to the standard approach and we actually have a couple of approaches available to us.

The first possible approach is to specify a headers property in the object passed to apiFetch(). e.g;

import apiFetch from "@wordpress/api-fetch";
apiFetch({
path: '/wp-json/some/endpoint',
headers: {'X-WP-Nonce': window.myvars.nonce}
}).then((data) => {
// use data here
});

This is fine and works it would mean having to define that same property on all requests which can be problematic if we need to change it later.

Fortunately, the @wordpress/api-fetch package supports adding middleware and provides us with a utility which handles the addition of the X-WP-Nonce request header. We just need to tell the apiFetch object to use nonce middleware and hand it our nonce. e.g;

import apiFetch from "@wordpress/api-fetch";
// Add the nonce as middleware. This automatically adds the `X-WP-Nonce`
// header to requests.
apiFetch.use( apiFetch.createNonceMiddleware( window.myvars.nonce ) );
apiFetch({
path: '/wp-json/some/endpoint'
}).then((data) => {
// use data here
});

The benefit of doing it this way is that we only define our nonce once and all requests will then have the X-WP-Nonce request header. We also don’t have to worry about specifying the X-WP-Nonce part as the package handles all that for us.

Making our nonce available to our script using wp_localize_script()

In the examples above, you’ll note that we are using a nonce at window.myvars.nonce. This is something that I’ve added to the DOM using WordPress’ wp_localize_script() function. e.g;

<?php
add_action('wp_enqueue_scripts', function(){
// Assuming our previous example code is in a script enqueued with the handle `my-script` e.g;
// wp_enqueue_script( 'my-script', … );
// Localise an object containing our nonce:
wp_localize_script( 'my-script', 'myvars', [
'nonce' => wp_create_nonce( 'wp_rest' )
]);
});

It’s important to note that if we don’t do this step the nonce value won’t be available and our script will fail due to undefined variables. Also note that the action passed to wp_create_nonce() must be 'wp_rest' or requests using this nonce will not authenticate.

About the author

Phil Kurth is a web developer living in Melbourne, Australia. Phil has a long history of WordPress development and enjoys building tools to empower others in their web design/development practice.

When not working with the web, Phil is usually spending time with his two young sons or is out hiking through the Australian bush.

Good dev stuff, delivered.

Product news, tips, and other cool things we make.

We never share your data. Read our Privacy Policy

© 2022 Hookturn Digital. All rights reserved.