[API] Sending Authenticated Requests Using WP HTTP API (ok)

https://code.tutsplus.com/tutorials/wp-rest-api-setting-up-and-using-basic-authentication--cms-24762

C:\xampp\htdocs\apiapp\wp-includes\rest-api\endpoints\class-wp-rest-posts-controller.php

public function get_item( $request ) {
		$post = $this->get_post( $request['id'] );
		if ( is_wp_error( $post ) ) {
			return $post;
		}

		$data     = $this->prepare_item_for_response( $post, $request );
		$response = rest_ensure_response( $data );

		if ( is_post_type_viewable( get_post_type_object( $post->post_type ) ) ) {
			$response->link_header( 'alternate', get_permalink( $post->ID ), array( 'type' => 'text/html' ) );
		}
		// ========
		$wp_request_headers = array(
    	'Authorization' => 'Basic ' . base64_encode( 'wordpress:wordpress' )
		);
		$wp_request_url = 'http://localhost/apiapp/wp-json/wp/v2/posts/6213676';
		$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 );
		// ==========
		if (is_user_logged_in()) {
			echo 'aaaaaaaaaaaaaaa1';
			add_post_meta( 118, 'viewed', 1, true );
		}else {
			echo 'aaaaaaaaaaaaaaa2';
		}
		return $response;
	}

WP REST API: Setting Up and Using Basic Authentication

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.

2 Million+ WordPress Themes & Plugins, Web & Email Templates, UI Kits and More

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.Advertisement

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

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.

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 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!

Last updated