Home >CMS Tutorial >WordPress >OAuth, Twitter, the WordPress HTTP API and You
In previous tutorials, we took a deep dive into the WordPress HTTP API. We even went as far as building the following plugins to demonstrate real-world examples of its usage: domain whois and social data widget; CAPTCHA protection plugin for WordPress login, registration & comment; and plugin for stopping disposable email address signup.
In this tutorial, we’ll be introduced to the world of OAuth, how Twitter uses it for authorizing HTTP requests to its API and finally, building a PHP class powered by WordPress HTTP API that plugins can take advantage of when consuming Twitter.
OAuth is an authentication protocol that provides a simple, safer and more secure way to publish and interact with protected data. It allows users to approve applications to act on their behalf without sharing their password.
If you’re storing protected data on your users’ behalf, they shouldn’t be spreading their passwords around the web to get access to it. Instead, you can use OAuth to give your users access to their data, while protecting their account credentials.
A run-down on how HTTP requests to Twitter are made with OAuth authentication will be explained as we code the PHP class.
First off, head over to Twitter’s Application management center; create an application to grab your keys and access token.
A step-by-step guide on creating Twitter applications and getting the API keys can be found at hostoople.com
Create the PHP class and include the properties that will store the various parameters. These are outlined below.
<span>class Twitter_API_WordPress { </span> <span>/** <span>@var <span>string</span> OAuth access token */</span> </span> <span>private $oauth_access_token; </span> <span>/** <span>@var <span>string</span> OAuth access token secrete */</span> </span> <span>private $oauth_access_token_secret; </span> <span>/** <span>@var <span>string</span> Consumer key */</span> </span> <span>private $consumer_key; </span> <span>/** <span>@var <span>string</span> consumer secret */</span> </span> <span>private $consumer_secret; </span> <span>/** <span>@var <span>array</span> POST parameters */</span> </span> <span>private $post_fields; </span> <span>/** <span>@var <span>string</span> GET parameters */</span> </span> <span>private $get_field; </span> <span>/** <span>@var <span>array</span> OAuth credentials */</span> </span> <span>private $oauth_details; </span> <span>/** <span>@var <span>string</span> Twitter's request URL */</span> </span> <span>private $request_url; </span> <span>/** <span>@var <span>string</span> Request method or HTTP verb */</span> </span> <span>private $request_method;</span>
The constructor will accept an array of your Twitter’s application consumer (or API) key and secret, as well as access token and access token secret and save them to their respective properties.
<span>/** Class constructor */ </span> <span>public function __construct( $settings ) { </span> <span>if ( ! isset( $settings['oauth_access_token'] ) </span> <span>|| ! isset( $settings['oauth_access_token_secret'] ) </span> <span>|| ! isset( $settings['consumer_key'] ) </span> <span>|| ! isset( $settings['consumer_secret'] ) </span> <span>) { </span> <span>return new WP_Error( 'twitter_param_incomplete', 'Make sure you are passing in the correct parameters' ); </span> <span>} </span> <span>$this->oauth_access_token = $settings['oauth_access_token']; </span> <span>$this->oauth_access_token_secret = $settings['oauth_access_token_secret']; </span> <span>$this->consumer_key = $settings['consumer_key']; </span> <span>$this->consumer_secret = $settings['consumer_secret']; </span> <span>}</span>
Next are the methods that will accept the GET or POST parameters for the HTTP request.
<span>/** </span><span> * Store the POST parameters </span><span> * </span><span> * <span>@param <span>array</span> $array array of POST parameters </span></span><span> * </span><span> * <span>@return $this </span></span><span> */ </span> <span>public function set_post_fields( array $array ) { </span> <span>$this->post_fields = $array; </span> <span>return $this; </span> <span>} </span> <span>/** </span><span> * Store the GET parameters </span><span> * </span><span> * <span>@param $string </span></span><span> * </span><span> * <span>@return $this </span></span><span> */ </span> <span>public function set_get_field( $string ) { </span> <span>$this->getfield = $string; </span> <span>return $this; </span> <span>}</span>
The private method _build_signature_base_string() accepts the following arguments to create the signature base string: the request URL, the request method or HTTP verb and the OAuth credentials (consumer key and secret; access token and secret; and the GET parameters if it is a GET request).
<span>/** </span><span> * Create a signature base string from list of arguments </span><span> * </span><span> * <span>@param <span>string</span> $request_url request url or endpoint </span></span><span> * <span>@param <span>string</span> $method HTTP verb </span></span><span> * <span>@param <span>array</span> $oauth_params Twitter's OAuth parameters </span></span><span> * </span><span> * <span>@return <span>string</span> </span></span><span> */ </span> <span>private function _build_signature_base_string( $request_url, $method, $oauth_params ) { </span> <span>// save the parameters as key value pair bounded together with '&' </span> <span>$string_params = array(); </span> <span>ksort( $oauth_params ); </span> <span>foreach ( $oauth_params as $key => $value ) { </span> <span>// convert oauth parameters to key-value pair </span> <span>$string_params[] = "<span><span>$key</span>=<span>$value</span>"</span>; </span> <span>} </span> <span>return "<span><span>$method</span>&"</span> . rawurlencode( $request_url ) . '&' . rawurlencode( implode( '&', $string_params ) ); </span> <span>}</span>
The _generate_oauth_signature() private method accepts the created signature base string to generate the OAuth signature.
<span>private function _generate_oauth_signature( $data ) { </span> <span>// encode consumer and token secret keys and subsequently combine them using & to a query component </span> <span>$hash_hmac_key = rawurlencode( $this->consumer_secret ) . '&' . rawurlencode( $this->oauth_access_token_secret ); </span> <span>$oauth_signature = base64_encode( hash_hmac( 'sha1', $data, $hash_hmac_key, true ) ); </span> <span>return $oauth_signature; </span><span>}</span>
The build_oauth() creates an array containing the following data and saves it to the oauth_details property, which will be use later by authorization_header() to generate the authorization header.
The request method or HTTP verb is also saved to request_method property.
<span>/** </span><span> * Build, generate and include the OAuth signature to the OAuth credentials </span><span> * </span><span> * <span>@param <span>string</span> $request_url Twitter endpoint to send the request to </span></span><span> * <span>@param <span>string</span> $request_method Request HTTP verb eg GET or POST </span></span><span> * </span><span> * <span>@return $this </span></span><span> */ </span> <span>public function build_oauth( $request_url, $request_method ) { </span> <span>if ( ! in_array( strtolower( $request_method ), array( 'post', 'get' ) ) ) { </span> <span>return new WP_Error( 'invalid_request', 'Request method must be either POST or GET' ); </span> <span>} </span> <span>$oauth_credentials = array( </span> <span>'oauth_consumer_key' => $this->consumer_key, </span> <span>'oauth_nonce' => time(), </span> <span>'oauth_signature_method' => 'HMAC-SHA1', </span> <span>'oauth_token' => $this->oauth_access_token, </span> <span>'oauth_timestamp' => time(), </span> <span>'oauth_version' => '1.0' </span> <span>); </span> <span>if ( ! is_null( $this->get_field ) ) { </span> <span>// remove question mark(?) from the query string </span> <span>$get_fields = str_replace( '?', '', explode( '&', $this->get_field ) ); </span> <span>foreach ( $get_fields as $field ) { </span> <span>// split and add the GET key-value pair to the post array. </span> <span>// GET query are always added to the signature base string </span> <span>$split = explode( '=', $field ); </span> <span>$oauth_credentials[ $split[0] ] = $split[1]; </span> <span>} </span> <span>} </span> <span>// convert the oauth credentials (including the GET QUERY if it is used) array to query string. </span> <span>$signature = $this->_build_signature_base_string( $request_url, $request_method, $oauth_credentials ); </span> <span>$oauth_credentials['oauth_signature'] = $this->_generate_oauth_signature( $signature ); </span> <span>// save the request url for use by WordPress HTTP API </span> <span>$this->request_url = $request_url; </span> <span>// save the OAuth Details </span> <span>$this->oauth_details = $oauth_credentials; </span> <span>$this->request_method = $request_method; </span> <span>return $this; </span> <span>}</span>
Here is the code for the authorization_header() method we talked about.
<span>/** </span><span> * Generate the authorization HTTP header </span><span> * <span>@return <span>string</span> </span></span><span> */ </span> <span>public function authorization_header() { </span> <span>$header = 'OAuth '; </span> <span>$oauth_params = array(); </span> <span>foreach ( $this->oauth_details as $key => $value ) { </span> <span>$oauth_params[] = "<span><span>$key</span>=\""</span> . rawurlencode( $value ) . '"'; </span> <span>} </span> <span>$header .= implode( ', ', $oauth_params ); </span> <span>return $header; </span> <span>}</span>
The process_request() will send the GET or POST request using wp_remote_get() or wp_remote_post() depending on the request method and subsequently return the response using wp_remote_retrieve_body().
<span>/** </span><span> * Process and return the JSON result. </span><span> * </span><span> * <span>@return <span>string</span> </span></span><span> */ </span> <span>public function process_request() { </span> <span>$header = $this->authorization_header(); </span> <span>$args = array( </span> <span>'headers' => array( 'Authorization' => $header ), </span> <span>'timeout' => 45, </span> <span>'sslverify' => false </span> <span>); </span> <span>if ( ! is_null( $this->post_fields ) ) { </span> <span>$args['body'] = $this->post_fields; </span> <span>$response = wp_remote_post( $this->request_url, $args ); </span> <span>return wp_remote_retrieve_body( $response ); </span> <span>} </span> <span>else { </span> <span>// add the GET parameter to the Twitter request url or endpoint </span> <span>$url = $this->request_url . $this->get_field; </span> <span>$response = wp_remote_get( $url, $args ); </span> <span>return wp_remote_retrieve_body( $response ); </span> <span>} </span> <span>}</span>
See this tutorial for a better understanding of the WordPress HTTP API and how it works.
And finally, we close the class.
<span>} // Twitter_API_WordPress</span>
Please note: In set_post_fields(), set_get_field() and build_oauth(), the object $this is returned in each method in order to support method chaining.
Example:
<span>$SomeObject->getObjectOne()->getObjectTwo()</span>
See the class usage below for a better understanding.
This class must be used within the context of a WordPress plugin. It won’t work as a standalone class because it requires the WordPress HTTP API for it to work.
To get a list or collection of your most recent tweets, follow the guide below. Note: https://api.twitter.com/1.1/statuses/user_timeline.json is the resource URL for retrieving the recent tweet data.
First, create an array of your access keys and tokens.
<span>class Twitter_API_WordPress { </span> <span>/** <span>@var <span>string</span> OAuth access token */</span> </span> <span>private $oauth_access_token; </span> <span>/** <span>@var <span>string</span> OAuth access token secrete */</span> </span> <span>private $oauth_access_token_secret; </span> <span>/** <span>@var <span>string</span> Consumer key */</span> </span> <span>private $consumer_key; </span> <span>/** <span>@var <span>string</span> consumer secret */</span> </span> <span>private $consumer_secret; </span> <span>/** <span>@var <span>array</span> POST parameters */</span> </span> <span>private $post_fields; </span> <span>/** <span>@var <span>string</span> GET parameters */</span> </span> <span>private $get_field; </span> <span>/** <span>@var <span>array</span> OAuth credentials */</span> </span> <span>private $oauth_details; </span> <span>/** <span>@var <span>string</span> Twitter's request URL */</span> </span> <span>private $request_url; </span> <span>/** <span>@var <span>string</span> Request method or HTTP verb */</span> </span> <span>private $request_method;</span>
Set the request URL and Method where w3guy is your Twitter username.
<span>/** Class constructor */ </span> <span>public function __construct( $settings ) { </span> <span>if ( ! isset( $settings['oauth_access_token'] ) </span> <span>|| ! isset( $settings['oauth_access_token_secret'] ) </span> <span>|| ! isset( $settings['consumer_key'] ) </span> <span>|| ! isset( $settings['consumer_secret'] ) </span> <span>) { </span> <span>return new WP_Error( 'twitter_param_incomplete', 'Make sure you are passing in the correct parameters' ); </span> <span>} </span> <span>$this->oauth_access_token = $settings['oauth_access_token']; </span> <span>$this->oauth_access_token_secret = $settings['oauth_access_token_secret']; </span> <span>$this->consumer_key = $settings['consumer_key']; </span> <span>$this->consumer_secret = $settings['consumer_secret']; </span> <span>}</span>
Finally, process the request like so.
<span>/** </span><span> * Store the POST parameters </span><span> * </span><span> * <span>@param <span>array</span> $array array of POST parameters </span></span><span> * </span><span> * <span>@return $this </span></span><span> */ </span> <span>public function set_post_fields( array $array ) { </span> <span>$this->post_fields = $array; </span> <span>return $this; </span> <span>} </span> <span>/** </span><span> * Store the GET parameters </span><span> * </span><span> * <span>@param $string </span></span><span> * </span><span> * <span>@return $this </span></span><span> */ </span> <span>public function set_get_field( $string ) { </span> <span>$this->getfield = $string; </span> <span>return $this; </span> <span>}</span>
If all goes well, the variable $result will be populated with a JSON data of your recent tweets.
For a POST request, for example, say you want to update your profile description.
<span>/** </span><span> * Create a signature base string from list of arguments </span><span> * </span><span> * <span>@param <span>string</span> $request_url request url or endpoint </span></span><span> * <span>@param <span>string</span> $method HTTP verb </span></span><span> * <span>@param <span>array</span> $oauth_params Twitter's OAuth parameters </span></span><span> * </span><span> * <span>@return <span>string</span> </span></span><span> */ </span> <span>private function _build_signature_base_string( $request_url, $method, $oauth_params ) { </span> <span>// save the parameters as key value pair bounded together with '&' </span> <span>$string_params = array(); </span> <span>ksort( $oauth_params ); </span> <span>foreach ( $oauth_params as $key => $value ) { </span> <span>// convert oauth parameters to key-value pair </span> <span>$string_params[] = "<span><span>$key</span>=<span>$value</span>"</span>; </span> <span>} </span> <span>return "<span><span>$method</span>&"</span> . rawurlencode( $request_url ) . '&' . rawurlencode( implode( '&', $string_params ) ); </span> <span>}</span>
The structure and code of this class was inspired by James Mallison’s PHP Twitter client.
To learn more about Twitter API and OAuth, see the resources below.
In this article, we learned about OAuth and how to consume Twitter using an HTTP client class powered by WordPress HTTP API. As previously stated, this class should be used within a WordPress plugin because it uses the WordPress HTTP API, which is only present or instantiated when WordPress is loaded. This PHP class can come in handy in building, for example, a recent tweets widget.
The code is available on GitHub. Feel free to fork and even submit pull requests.
Be sure to subscribe to the WordPress channel to keep abreast of my upcoming tutorials.
Happy Coding.
Setting up OAuth2 on your WordPress site involves installing and configuring an OAuth2 plugin. You can choose from several plugins available on the WordPress plugin directory. Once you’ve installed the plugin, you’ll need to configure it with your OAuth2 provider’s details, including the client ID and client secret. You may also need to set up redirect URLs and scopes, depending on your provider’s requirements.
OAuth plays a crucial role in Twitter API by providing secure delegated access. It allows users to grant third-party applications access to their Twitter account without sharing their password. This means applications can interact with Twitter on your behalf, performing actions like tweeting, reading your timeline, and following new users.
Deploying error API issues in Twitter can be fixed by ensuring that your application is correctly configured and that you’re using the correct API keys. You should also ensure that your application is not exceeding Twitter’s rate limits. If you’re still experiencing issues, it may be worth reaching out to Twitter’s developer support for further assistance.
OAuth1.0 and OAuth2.0 are both protocols for secure API authorization. However, OAuth2.0 is a more streamlined and powerful protocol. It offers more flexibility for developers and can be used for applications on a variety of platforms, including mobile and desktop applications. OAuth1.0, on the other hand, is more complex and less flexible.
The WordPress HTTP API can be used to send HTTP requests from your WordPress site. This can be useful for interacting with external APIs, such as the Twitter API. To use the WordPress HTTP API, you’ll need to use the wp_remote_get or wp_remote_post functions, passing in the URL of the API endpoint you want to interact with.
Securing your OAuth tokens is crucial to prevent unauthorized access to your application. You should always store your tokens securely, such as in a secure database, and never expose them in client-side code. You should also implement token expiration and refresh tokens to ensure that even if a token is compromised, it can’t be used indefinitely.
Some common issues faced while integrating OAuth with WordPress include incorrect configuration of the OAuth plugin, issues with redirect URLs, and problems with the OAuth provider’s API. These issues can usually be resolved by carefully checking your configuration and ensuring that you’re using the correct API keys and redirect URLs.
Troubleshooting issues with the Twitter API can involve checking your application’s configuration, ensuring that you’re using the correct API keys, and checking that your application is not exceeding Twitter’s rate limits. You can also use Twitter’s API reference documentation to understand the expected behavior of the API and to identify any potential issues.
To use OAuth2.0 with the Twitter API, you’ll need to create a Twitter application and obtain your API keys. You’ll then need to use these keys to obtain an access token, which can be used to authenticate your API requests. Note that Twitter’s implementation of OAuth2.0 is application-only, meaning it can only be used for requests that don’t require user context.
The MiniOrange OAuth 2.0 Server plugin for WordPress provides a simple and secure way to set up an OAuth2.0 server on your WordPress site. It supports multiple grant types, including authorization code, implicit, password, and client credentials, and it also supports JWT and SAML. This makes it a flexible and powerful choice for implementing OAuth2.0 on your WordPress site.
The above is the detailed content of OAuth, Twitter, the WordPress HTTP API and You. For more information, please follow other related articles on the PHP Chinese website!