Table of Contents
1.0 Introduction
2.0 Deriving Authorization
HTTP Request Header Value
2.1 … Twitter generated OAuth params
2.2 … oauth_signature
2.3 … Building the OAuth Header Value
3.0 Invoking the Twitter API using cURL
4.0 Summary
5.0 Appendix
5.1 … Reference
5.2 … The Twitter Class
1.0 Introduction
Recently Twitter retired 1.0 APIs. With 1.1 APIs, Twitter mandates authentication. True, OAuth 1.0a based authentication. So gone are the days when we were able to access Twitter feeds using 1.0 APIs without authentication. No worries though. Twitter expects a valid value for HTTP header Authorization similar to the one shown below.
> GET /1.1/statuses/user_timeline.json?screen_name=sangeethlabs&trim_user=1&include_entities=&exclude_replies=1&include_rts=&count=1 HTTP/1.1
> Host: api.twitter.com
> Accept: */*
> Authorization: OAuth oauth_consumer_key="sdfERdf3434sdWEddf23d", oauth_nonce="1373207246", oauth_signature_method="HMAC-SHA1", oauth_token="8749687284-XrindkI9QRm3ab8MWcQg4kXCYTz1NOS8yF1E2FFGN", oauth_timestamp="1373207246", oauth_version="1.0", oauth_signature="%2FpEI6thDB7zCYjkS93Jb8D%2FuQWjS%3D"
In order to derive the Authorization header value, we need values for the following components.
- oauth_consumer_key
- oauth_nonce
- oauth_token
- oauth_timestamp
- oauth_signature
The following sections explain how the above components are derived, how it can be implemented using PHP and finally shows a simple example to fetch the latest tweet using /statuses/user_timeline
API.
2.0 Deriving Authorization
HTTP Request Header Value
2.1 Twitter generated OAuth params
The values for oauth_consumer_key
and oauth_token
need to be created from Twitter website by following the steps mentioned below
- Sign Up for Twitter in case you do not have one.
- Create a new Application using Twitter and get the
consumer_key
andconsumer_secret
. - Create your OAuth access token and secret (i.e
oauth_access_token
andoauth_access_token_secret
).
NOTE: Once you create an Application, the same page guides you to generate the OAuth access token.
So at this stage the OAuth parameters for which we have the values are
OAuth Param | Value |
---|---|
oauth_consumer_key |
consumer_key |
oauth_token |
oauth_access_token |
The values of consumer_secret
and oauth_access_token_secret
are required for creating oauth_signature
.
2.2 oauth_signature
In order to create the value for oauth_signature, I would recommend you to read the article named Creating a signature at Twitter developers website. In order to help PHP developers, I have translated the steps into PHP.
Step 1: Collecting the request method and URL
Since our objective is to fetch the latest tweets,
Request method | GET |
---|---|
Base URL | https://api.twitter.com/1.1/statuses/user_timeline.json |
Step 2: Collecting parameters
In order to get the latest tweets from @sangeethlabs, the list of Request-parameters required are
Request Param | Value |
---|---|
screen_name | sangeethlabs |
trim_user | true |
include_entities | false |
exclude_replies | true |
include_rts | false |
count | 1 |
NOTE: In order to know the meaning of each of the above request parameters, please read the manual of /statuses/user_timeline
API.
Further, All OAuth-parameters other than oauth_signature are also considered as parameters. So we have
OAuth Param | Value |
---|---|
oauth_consumer_key | consumer_key |
oauth_nonce | (The current time) |
oauth_signature_method | HMAC-SHA1 |
oauth_token | oauth_access_token |
oauth_timestamp | (The current time) |
oauth_version | 1.0 |
The following code helps to create the Parameter string.
<?php
$v = array();
$all_params = array_merge($oauthParams, $requestParams);
ksort($all_params);
foreach($all_params as $key=>$value) {
$v[] = "$key=" . rawurlencode($value);
}
$parameterString = rawurlencode(implode('&', $v));
?>
Step 3: Creating the signature base string
The following code helps to create the Signature base string which then used to create the signature.
<?php
$signatureBaseString = $httpMethod
. '&'
. rawurlencode($baseURI)
. '&'
. $parameterString;
?>
Step 4: Getting a signing key
The following code show how to create a Signing key
<?php
$signing_key = rawurlencode($consumer_secret)
. '&'
. rawurlencode($oauth_access_token_secret);
?>
Step 5: Calculating the signature
<?php
$oauth_signature = base64_encode(hash_hmac('sha1', $signature_base_string, $signing_key, true));
?>
2.3 Building the OAuth Header Value
<?php
$values = array();
foreach($oauthParams as $key=>$value) {
$values[] = "$key=\"" . rawurlencode($value) . "\"";
}
$headerValue = 'OAuth ' . implode(', ', $values);
?>
Finally, we have the value for HTTP header Authorization . The following sections will show how to use the OAuth header value and invoke /statuses/user_timeline
API.
3.0 Invoking the Twitter API using cURL
In order to invoke the Twitter API as mentioned above we need the following parameters
- url
- request params
- authorization header value
In the previous sections we have computed the values for these three parameters. With these parameters, we can use the following code to invoke the Twitter API using cURL
.
<?php
// Invoke the Twitter API using cURL functions
$ch = curl_init();
// Create the API URI appended with the query parameters
$url = $this->buildURL($url, $requestParams);
$values = array();
foreach($queryParams as $key=>$value) {
$values[] = "$key=" . rawurlencode($value);
}
$queryString = implode('&', $values);
return "$url?$queryString";
curl_setopt_array($ch,
array(
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => array("Authorization: $authorization_header_value"),
CURLOPT_HEADER => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false
));
$twitter_response = curl_exec($ch);
if (empty($twitter_response)) {
$errorMessage = curl_error($ch);
curl_close($ch);
throw new Exception($errorMessage);
}
$info = curl_getinfo($ch);
curl_close($ch);
$json = json_decode($twitter_response, true);
$responseCode = $info['http_code'];
if ($responseCode != '200') {
throw new Exception($json['errors'][0]['message'],
$json['errors'][0]['code']);
}
?>
4.0 Summary
Now using our new Twitter
class and with the values of oauth_access_token
, oauth_access_token_secret
, consumer_key
and consumer_secret
, we can invoke /statuses/user_timeline
API to get the latest tweet from @sangeethlabs as shown below
<?php
$oauth_access_token = "...YOUR OAUTH ACCESS TOKEN...";
$oauth_access_token_secret = "...YOUR OAUTH ACCESS TOKEN SECRET...";
$consumer_key = "...YOUR CONSUMER KEY...";
$consumer_secret = "...YOUR CONSUMER SECRET...";
$twitter = new Twitter($oauth_access_token,
$oauth_access_token_secret,
$consumer_key,
$consumer_secret);
//$twitter->setVerboseEnabled(true);
try {
$json = $twitter->get("/statuses/user_timeline.json",
array(
'screen_name'=>'sangeethlabs',
'trim_user'=> true,
'include_entities'=> false,
'exclude_replies'=> true,
'include_rts' => true,
'count' => 1
));
echo "Last Tweet\n"
. "Time: " . $json[0]['created_at'] . "\n"
. "Text: " . $json[0]['text'] . "\n\n";
} catch (Exception $e) {
echo "Error: {$e->getCode()} - {$e->getMessage()}\n";
}
?>
5.0 Appendix
5.1 Reference
- stackoverflow.com – Simplest PHP example for retrieving user_timeline with Twitter API version 1.1
- twitter.com – GET statuses/user_timeline
- twitter.com – Creating a signature
- twitter.com – Authorizing a request
- ietf.org – The OAuth 1.0 protocol
- php.net – cURL Functions
5.2 The Twitter Class
1 <?php
2 class Twitter {
3 private $oauth_access_token = "";
4 private $oauth_access_token_secret = "";
5 private $consumer_key = "";
6 private $consumer_secret = "";
7 private $verboseEnabled = false;
8
9 function __construct($oauth_access_token,
10 $oauth_access_token_secret,
11 $consumer_key,
12 $consumer_secret) {
13 $this->oauth_access_token = $oauth_access_token;
14 $this->oauth_access_token_secret = $oauth_access_token_secret;
15 $this->consumer_key = $consumer_key;
16 $this->consumer_secret = $consumer_secret;
17 }
18
19 private function buildSignatureBaseString($httpMethod, $baseURI, $requestParams, $oauthParams) {
20 // Collecting parameters an building the 'Parameter string'
21 $v = array();
22 $all_params = array_merge($oauthParams, $requestParams);
23 ksort($all_params);
24
25 foreach($all_params as $key=>$value) {
26 $v[] = "$key=" . rawurlencode($value);
27 }
28 $parameterString = rawurlencode(implode('&', $v));
29
30 // Building the 'Signature base string'
31 return $httpMethod
32 . '&'
33 . rawurlencode($baseURI)
34 . '&'
35 . $parameterString;
36 }
37
38 private function buildAuthorizationHeaderValue($oauthParams) {
39 $r = 'OAuth ';
40 $values = array();
41 foreach($oauthParams as $key=>$value) {
42 $values[] = "$key=\"" . rawurlencode($value) . "\"";
43 }
44 $r .= implode(', ', $values);
45 return $r;
46 }
47
48 private function buildOuthSignature($signature_base_string) {
49 $signing_key = rawurlencode($this->consumer_secret)
50 . '&'
51 . rawurlencode($this->oauth_access_token_secret);
52
53 $oauth_signature = base64_encode(hash_hmac('sha1', $signature_base_string, $signing_key, true));
54
55 return $oauth_signature;
56 }
57
58 private function buildURL($url, $queryParams) {
59 $values = array();
60 foreach($queryParams as $key=>$value) {
61 $values[] = "$key=" . rawurlencode($value);
62 }
63 $queryString = implode('&', $values);
64 return "$url?$queryString";
65 }
66
67 public function setVerboseEnabled($verboseEnabled) {
68 $this->verboseEnabled = $verboseEnabled;
69 }
70
71 public function get($api, $requestParams) {
72 $url = "https://api.twitter.com/1.1". $api;
73
74 $oauthParams = array( 'oauth_consumer_key' => $this->consumer_key,
75 'oauth_nonce' => time(),
76 'oauth_signature_method' => 'HMAC-SHA1',
77 'oauth_token' => $this->oauth_access_token,
78 'oauth_timestamp' => time(),
79 'oauth_version' => '1.0');
80
81 $signature_base_string = $this->buildSignatureBaseString('GET', $url, $requestParams, $oauthParams);
82 if ($this->verboseEnabled) {
83 echo "Signature base string:\n$signature_base_string\n\n";
84 }
85
86 $oauth_signature = $this->buildOuthSignature($signature_base_string);
87 if ($this->verboseEnabled) {
88 echo "OAuth signature:\n$oauth_signature\n\n";
89 }
90 $oauthParams['oauth_signature'] = $oauth_signature;
91
92 $authorization_header_value = $this->buildAuthorizationHeaderValue($oauthParams);
93 if ($this->verboseEnabled) {
94 echo "Authorization header:\nAuthorization: $authorization_header_value\n\n";
95 }
96
97 // Invoke the Twitter API using cURL functions
98 $ch = curl_init();
99
100 // Create the API URI appended with the query parameters
101 $url = $this->buildURL($url, $requestParams);
102 if ($this->verboseEnabled) {
103 echo "Request URL:\n$url\n\n";
104 }
105 curl_setopt_array($ch,
106 array(
107 CURLOPT_URL => $url,
108 CURLOPT_HTTPHEADER => array("Authorization: $authorization_header_value"),
109 CURLOPT_HEADER => false,
110 CURLOPT_RETURNTRANSFER => true,
111 CURLOPT_SSL_VERIFYPEER => false
112 ));
113 if ($this->verboseEnabled) {
114 curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
115 }
116 $twitter_response = curl_exec($ch);
117
118 if (empty($twitter_response)) {
119 $errorMessage = curl_error($ch);
120 curl_close($ch);
121 throw new Exception($errorMessage);
122 }
123
124 $info = curl_getinfo($ch);
125
126 curl_close($ch);
127
128 if ($this->verboseEnabled) {
129 echo "Response Body:\n$twitter_response\n\n";
130 }
131
132 $json = json_decode($twitter_response, true);
133
134 $responseCode = $info['http_code'];
135 if ($responseCode != '200') {
136 throw new Exception($json['errors'][0]['message'],
137 $json['errors'][0]['code']);
138 }
139
140 unset( $requestParams );
141 unset( $oauthParams );
142
143 return $json;
144 }
145 }
146 ?>