In the introductory part of this series, we had a quick refresher on REST architecture and how it can help us create better applications. We then explored the history of REST APIs in WordPress and introduced ourselves to the latest addition: the WP REST API plugin. We set up a basic working environment for testing with the plugin, which included plugin installation and an HTTP client for sending requests or viewing the server response.
In the current part of the series, we will set up a basic authentication protocol on the server to send authenticated requests to perform various tasks through the REST API.
To be specific, in this part we will:
- look at various authentication methods available when using the REST API plugin
- set up basic authentication on the server
- send authenticated request using Postman
- send authenticated request using JavaScript framework
- send authenticated request using command line
- send authenticated request using WP HTTP API
But let’s first take a look at the authentication itself.
What Is Authentication?
In its most basic definition, authentication is the process of determining the identity of a person.
According to Webopedia:
The process of identifying an individual, usually based on a username and password. In security systems, authentication is distinct from authorization , which is the process of giving individuals access to system objects based on their identity. Authentication merely ensures that the individual is who he or she claims to be, but says nothing about the access rights of the individual.
When talking about WP REST API, a user with sufficient privileges can perform various CRUD tasks such as creating a post, retrieving all the users of the site or revoke the rights of a user. But for all these actions one must prove his/her identity to the server, and that’s where authentication plays its part.
Without proper authentication, it would be very easy for someone with mischievous ambitions to mess around with the site, so authentication provides a necessary layer of security to restrict the rights of a user and the actions that could be performed.
Authentication With the WP REST API
The WP REST API provides three options for authentication, each intended for a specific purpose. These options are:
- basic authentication
- OAuth authentication
- cookie authentication
Right now, the native way to authenticate with WordPress is authentication by cookies. This is how WordPress determines the identity of a user and what actions it can perform. To use the other two authentication methods listed above with the WP REST API, we need to install their respective plugins provided by the WP REST API team available on GitHub. Hopefully, these two methods will also be included in the WordPress core with the REST API plugin itself.
Basic authentication is the most basic type of HTTP authentication, in which login credentials are sent along with the headers of the request.
How Basic Authentication Works
In basic authentication, the client requests a URL that requires authentication. The server requests the client (or user agent) to authenticate itself by sending a 401-Not Authorized code. The client, in return, sends back the same request but with login credentials as a base64 encoded string in the format username:password
. This string is sent in the Authorization
header field as the following:
Authorization: Basic {base64_encode(username:password)}
So if the username is tutsplus
and the password is 123456
, the following header field would be sent with the request:
Authorization: Basic dHV0c3BsdXM6MTIzNDU2
Since the base64 encoded string can easily be decoded, this method is highly insecure to be used on an open network. Hence this method should only be used for debugging and development purposes when the connection between the server and the client is trusted.
Installing the Plugin
As mentioned above, the plugin is available on GitHub from the WP REST API team. So all we need to do is to clone it in our plugins
directory and activate it.
Head over to your /wp-content/plugins/
directory and clone the plugin for which you may need sudo
rights to run the command. To do so, issue the following:
$ sudo git clone https://github.com/WP-API/Basic-Auth.git
The terminal will ask for your password. Enter your password and let the repository be cloned into a directory.
After cloning the plugin, activate it by going to your WP Admin. The basic HTTP authentication method can now be used with the REST API plugin.
Sending Authenticated Requests Using Postman
Most HTTP clients support sending a request using the basic authentication method natively, and so does Postman for Chrome. To send an authenticated request, go to the Authorization tab below the address bar:
Now select Basic Auth from the drop-down menu. You will be asked to enter your username and password. After entering your credentials, click the Update request button.
After updating the authentication option, you will see a change in the Headers tab, and it now includes a header field containing the encoded username and password string:
That’s all about how we set up basic authentication with Postman. Now you can send a test request like deleting a post, which requires authentication:
DELETE http://dev-server/wp-json/wp/v2/posts/52
Where dev-server
is the path to your development server.
If all goes well, the server will return a 200 OK status code, indicating that the post with an id of 52
has been deleted:
Don’t worry about the request we made here—we will be going through it in more detail in the future parts of the series.
Sending Authenticated Requests From the Command Line
We can use the command line to send authenticated requests using this method. Consider the following curl
equivalent of the above request:
curl --request DELETE -I --user admin:password http://dev-server/wp-json/wp/v2/posts/52
The following response would be sent by the server, indicating that everything is okay:
HTTP/1.1 200 OK Date: Fri, 28 Aug 2015 20:02:43 GMT Server: Apache/2.4.6 (CentOS) PHP/5.6.12 X-Powered-By: PHP/5.6.12 Set-Cookie: PHPSESSID=k0rg6mcbsie7ufvoav219lqre0; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache X-Content-Type-Options: nosniff Link: <http://localserver/wordpress-api/demo-post-28/>; rel="alternate"; type=text/html Allow: GET, POST, PUT, PATCH, DELETE Transfer-Encoding: chunked Content-Type: application/json; charset=UTF-8
The --request
option specifies the request method to be used, which in our case is DELETE
. You can also use -X
as an alternate to the --request
option.
The -I
option only fetches the HTTP headers sent by the server. The alternate to -I
is the --head
option.
Sending Authenticated Requests Using JavaScript
If you are using a client-side JavaScript framework, such as jQuery, to interact remotely with a WordPress site having WP API enabled, you can send the authorization headers in an AJAX request. Consider the following DELETE
request sent through the jQuery.ajax()
method:
$.ajax({ url: 'http://dev-server/wp-json/wp/v2/posts/52', method: 'DELETE', crossDomain: true, beforeSend: function ( xhr ) { xhr.setRequestHeader( 'Authorization', 'Basic ' + Base64.encode( 'username:password' ) ); }, success: function( data, txtStatus, xhr ) { console.log( data ); console.log( xhr.status ); } });
Where Base64
is an object used for encoding and decoding a base64 string. It’s defined as follows, prior to the above jQuery.ajax()
method call:
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}};
I found it on StackOverflow, and it’s a cross browser way of encoding and decoding a base64 string in JavaScript.
In the above request, we set the Authorization
header using the setRequestHeader()
method of the xhr
object passed as an argument to the beforeSend()
method.
In addition to the above request, the Access-Control-Allow-Headers
headers should allow the Authorization
field on the server. This can be enabled by adding the following line of code in your WordPress .htaccess file:
Header always set Access-Control-Allow-Headers Authorization Header always set
The above request, when completed, will echo out the response in your browser’s console as shown in the figure below:
The 200 status response code returned by the server shows that the post with an id of 52
has been deleted successfully.
Sending Authenticated Requests Using WP HTTP API
If you are interacting remotely with another WordPress site from your WordPress installation, the most appropriate way to send HTTP requests is the WP HTTP API.
Consider the following code that sends a DELETE
request to another WordPress installation with WP REST API and basic authentication enabled:
$wp_request_headers = array( 'Authorization' => 'Basic ' . base64_encode( 'username:password' ) ); $wp_request_url = 'http://localserver/wordpress-api/wp-json/wp/v2/posts/52'; $wp_delete_post_response = wp_remote_request( $wp_request_url, array( 'method' => 'DELETE', 'headers' => $wp_request_headers ) ); echo wp_remote_retrieve_response_code( $wp_delete_post_response ) . ' ' . wp_remote_retrieve_response_message( $wp_delete_post_response );
Here we used the wp_remote_request()
function which accepts two arguments:
-
$url
: the URL of the request -
$args
: an array of additional arguments to be passed
The $method
defined in the $args
array is DELETE
, and it should always be written in uppercase. The $headers
array takes key value pairs of all the header fields to be passed with the request. We have passed the Authorization
key with a base64 encoded username and password string as its value.
The response would be saved in the $wp_delete_post_response
variable, which we can use with the wp_remote_retrieve_response_code()
and wp_remote_retrieve_response_message()
functions. These two functions are helper functions in the WP HTTP API, and they extract the status code and status message from the response respectively.
If the post is deleted successfully by the above request, the following text will be echoed out:
200 OK
That’s all about the basic authentication method supported by WP REST API. We will be using the same authentication method in our future parts for retrieving, creating, or modifying data due to its simplicity, unless mentioned otherwise.
Conclusion
In the current part of the series, we looked closely at the basic HTTP authentication method supported by WP REST API. However, it shouldn’t be used in live production environments due to the fact that the base64 encoded string could easily be decoded and your credentials might fall into the wrong hands.
After having successfully set up and tested the HTTP basic authentication method, we are ready to take a step further and set up a more sophisticated way of authentication—the OAuth 1.0a method. We will do that in the very next part of the series, so stay tuned!
Comments