Why authenticate and how?
The WordPress RESTful API was a major addition to the core ecosystem when it launched with WordPress 4.7. Having these endpoints opened up a slew of possibilities to be able to power the future of digital experiences. By using the REST API, developers are able to create native mobile and web applications that are driven by the WordPress backend. This is what’s referred to as a Headless WordPress site.
By default, anyone can make a GET request to any of the API endpoints for posts, pages, users, media, etc to garner data about your site and its information. WordPress Core has included a full list of REST API endpoints which can be found in the developer handbook here.. When it comes to creating posts or pages or adding information to your site via an API you don’t want any random person spamming your site with junk, and that is where authentication comes into play.
There’s a few options available for authentication. The easiest for development and testing purposes would be Basic Authentication, which requires that you send an appropriate username and password encoded in base64 with each request. You may have set up an .htpasswd file in conjunction with your .htaccess file in the past if you use Apache as your backend web server, and this is pretty similar to that, however instead of storing information in a hidden file, WordPress uses usernames and passwords from your database to authenticate. You can install the Basic Auth plugin from https://github.com/WP-API/Basic-Auth. Since this requires sending a username and password with every single request, I do not recommend using this in a production environment.
Another way of authenticating with the WordPress REST API would be to utilize JWT Authentication, or JSON Web Tokens, which is an open industry standard for representing claims securely between two parties. There’s a multitude of JWT Authentication plugins out there, but I typically see either the WP-API teams jwt-auth plugin used, which is still experimental, or the JWT Authentication for WP REST API plugin . Additionally Jonathan Dejong has also created a Simple JWT Authentication plugin, but they all seem to function on the same basic premises. Once this plugin is installed and configured you’ll need to generate a token to be able to prove that your application has the required permissions to access specific endpoints, such as showing all posts with the status of draft. By sending a POST request to the plugin’s token endpoint, containing a username and password combination, you’ll get back a token which you can use in the headers of future requests for authentication.
Testing Authentication and the REST API
So we’ve got our WordPress instance running, an authentication plugin setup and configured so now how do we make sure it is working as intended? Postman is my go to application for testing REST API calls. It’s interface is great, it has support for a multitude of platforms, and is just all around excellent, because let’s be real, who wants to write out long curl commands, manually setting headers, running the request again because you didn’t get all the information you needed. Sure that’s fine for a few people, but Postman simplifies the process tremendously.
When we make GET request to the posts endpoint we get back a JSON array that contains all of the posts on our site.
But if we change that GET to a POST we get a 401 Not Authorized error back, and this is because we haven’t authenticated our requests yet.
Basic Authentication with Postman
Let’s say the Basic Auth plugin is installed on our site, and we want to try to create a post. We can use a POST request to create a post within Postman. If you send a default POST request to the /wp-json/wp/v2/posts endpoint you’ll receive a 401 error. Click on the Authorization tab within Postman, and in the dropdown choose Basic Auth. To the right of that fill in your username and password you use for logging into the Admin Dashboard, and click Send.
You’ll get back a 400 response because we didn’t send any other data to WordPress to create a post.
If we fill in the required information as form-data on the Body tab in Postman, which in this case is Content, title, and excerpt we can create a draft post.
If you were to change the username or password in the Basic Auth settings you would get back a response telling you to reset your password. Just as a reminder, we don’t recommend the use of Basic Auth in production requests due to constantly having to pass your username and password.
JWT Authentication with Postman
JWT Authentication uses the Bearer authorization header rather than the Basic authorization header. To be able to generate the token for the header though we first have to make a request to the Token endpoint of our respective JWT Auth plugin to get this token, except you only need to pass in the username and password in the body of the request to generate the token. Once you have the token, you can then just send that in the headers instead of having to pass your username and password on every request.
On the Authorization tab in Postman, set the dropdown to No Auth, and change the request url to your JWT Authentication Token endpoint. For the body, set your username and password entries and submit your POST request to get your token.
Once you have that token, change the endpoint you want to authenticate against. Go back to the Authorization tab, change the dropdown from No Auth to Bearer and copy and paste your token into the Token field. Then create another post similar to what we did with the Basic Auth one. For the Body, ensure you have Content, title, and excerpt values and send your POST request. If everything is configured right you should get back a 200 response and see your new post’s JSON data in the bottom of Postman.
As Gutenberg becomes more prevalent in use throughout the WordPress community, I believe that REST API knowledge is going to become absolutely necessary. With different plugins extending WordPress’ core API, like Woocommerce’s API, this ll paves the way for some extremely slick digital experiences powered by WordPress as we move into the future. If you see anything I missed, or may not be 100% accurate about feel free to drop me a mention on Twitter, @wpdevlife.