I'm trying to create a script that uses the twitter streaming api to keep a tab on tweets with a certain hash-tag.
Whenever I try creating a request though, I always get a 401 Unauthorized return. Can anyone help me figure out what I'm doing incorrectly?
I tried to follow twitter's api to the dot, but apparently I'm doing something wrong. The code I have is below.
$base_url_string = urlencode($base_url);
$parameter_string = urlencode('oauth_consumer_key') . '=' . urlencode($consumer_key) . '&'
. urlencode('oauth_nonce') . '=' . urlencode($nonce) . '&'
. urlencode('oauth_signature_method') . '=' . urlencode($signature_method) . '&'
. urlencode('oauth_timestamp') . '=' . urlencode($timestamp) . '&'
. urlencode('oauth_token') . '=' . urlencode($token) . '&'
. urlencode('oauth_version') . '=' . urlencode($version) . '&'
. urlencode('track') . '=' . urlencode('#kitten');
$signature_base_string = $method . "&" . $base_url_string . "&" . urlencode($parameter_string);
$signature = base64_encode(hash_hmac('sha1', $signature_base_string, $secret, true));
$fp = fsockopen("ssl://stream.twitter.com", 443, $errno, $errstr, 30);
if (!$fp) {
print "$errstr ($errno)\n";
} else {
$request = $method . " /1.1/statuses/filter.json?" . urlencode("track") . "=" . urlencode("#kitten") . " HTTP/1.1\r\n";
$request .= "Host: stream.twitter.com\r\n";
$request .= 'Authorization: OAuth'
. ' oauth_consumer_key="' . $consumer_key . '",'
. ' oauth_nonce="' . $nonce . '",'
. ' oauth_signature="' . $signature . '",'
. ' oauth_signature_method="' . $signature_method . '",'
. ' oauth_timestamp="' . $timestamp . '",'
. ' oauth_token="' . $token . '",'
. ' oauth_version="' . $version . '"'
. "\r\n\r\n";
print $request . "</br>";
fwrite($fp, $request);
while (!feof($fp)) {
$json = fgets($fp);
echo $json;
$data = json_decode($json, true);
if ($data) {
print $data;
}
}
print 'exiting...';
fclose($fp);
}
Ok so I figured this all out. It was a combination of poor string manipulation and not Percent Encoding everything. Both the keys and values of the OAuth string must be Percent encoded. I had done that in the signature, but not in the actual request. Once I fixed that, the request got through and I was connected to the Twitter Streaming API.
Related
I've been stuck on this problem for like two days. I've written a Python script which makes a PUT request to AWS Pinpoint service.
Pinpoint like many other AWS services requires a signature authentification on requests, which I managed to handle in Python.
Right now I'm trying to translate my script into a PHP service for Symfony. When I run my first request to AWS pinpoint I get this:
The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
The Canonical String for this request should have been\n'PUT\n/v1/apps/.../endpoints/...\n\ncontent-type:application/json\nhost:pinpoint.eu-west-1.amazonaws.com\nx-amz-content-sha256:de98d86577f0e1...655e6de27154af1c05ab34\nx-amz-date:20191226T151542Z\nx-amz-security-token:IQoJb....\nx-amz-user-agent:aws-amplify/1.1.2 react-native aws-amplify/1.1.2 react-native callback\n\ncontent-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent\n0240a9479d0a66d74eaae42dc...95247aaa800fcbe5cf2
The String-to-Sign should have been
'AWS4-HMAC-SHA256\n20191226T151542Z\n20191226/eu-west-1/mobiletargeting/aws4_request\nb2c451534fe370503ecf4068b45c...63e91280cc3187ae3230034107
So I already checked if my Canonical String was wrong, it is the exact same AWS is asking. The String-to-Sign is different by the Canonical String hash.
Here's my headers function
public function create_headers($data,\DateTime $time,$canonical_uri,$method,$to_api=null)
{
$amz_date = $time->format('Ymd\THis\Z');
$date_stamp = $time->format('Ymd');
$payload_hash = hash('sha256',$data);#utf8_encode($data));
$canonical_querystring = "";
$canonical_headers = 'content-type:' . $this->content_type . '\n' . 'host:' . $this->host . '\n' . 'x-amz-content-sha256:' . $payload_hash . '\n' . 'x-amz-date:' . $amz_date . '\n' . 'x-amz-security-token:' . $this->security_token . '\n' . 'x-amz-user-agent:aws-amplify/1.1.2 react-native aws-amplify/1.1.2 react-native callback' . '\n';
$signed_headers = 'content-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent';
$canonical_request = $method . '\n' . $canonical_uri . '\n' . $canonical_querystring . '\n' . $canonical_headers . '\n' . $signed_headers . '\n' . $payload_hash;
echo '<br><br>';
print_r(str_replace('\n','<br>',$canonical_request));
#var_dump($canonical_request);
$algorithm = 'AWS4-HMAC-SHA256';
$credential_scope = "{$date_stamp}/{$this->region}/{$this->service}/aws4_request";
#$date_stamp . '/' . $this->region . '/' . $this->service . '/' . 'aws4_request';
#$credential_scope = $this->createScope($date_stamp,$this->region,$this->service);
echo '<br><br>';
#$string_to_sign = $algorithm . '\n' . $amz_date . '\n' . $credential_scope . '\n' . hash('sha256', utf8_encode($canonical_request));
$hash = hash('sha256', $canonical_request);
$string_to_sign = "AWS4-HMAC-SHA256\n{$amz_date}\n{$credential_scope}\n{$hash}";
print_r(str_replace('\n','<br>',$string_to_sign));
echo '<br><br>';
$signing_key = $this->get_signature_key($this->secret_key,$date_stamp,$this->region,$this->service);
$signature = hash_hmac('sha256',$string_to_sign,$signing_key);
$authorization_header = $algorithm . ' ' . 'Credential=' . $this->access_key . '/' . $credential_scope . ', ' . 'SignedHeaders=' . $signed_headers . ', ' . 'Signature=' . $signature;
$headers = array(
'host'=> $this->host,
'content-type'=> $this->content_type,
'x-amz-user-agent'=> 'aws-amplify/1.1.2 react-native aws-amplify/1.1.2 react-native callback',
'x-amz-content-sha256'=> $payload_hash,
'x-amz-security-token'=> $this->security_token,
'x-amz-date'=> $amz_date,
'authorization'=> $authorization_header
);
$this->s->headers = $headers;
return $headers;
}
I've been looking for my error for days but I think I need someone with a fresh eye...
Thank you!
After hours and hours of questionning myself, I've finally found why I was getting that error.
In PHP "\n" and '\n' doesn't have the same meaning.
"\n" is a real line break - which is what AWS is asking.
'\n' is a string of \ and n characters.
AWS API is still pretty shit though.
I'm trying to connect to the LivePerson Engagement History API and I'm running into an issue that I believe is related to the signature being generated.
First off, the API already provides the necessary consumer key, consumer secret, access token, and token secret. So I don't have to go through the process of retrieving those. In order to access their API I just have to provide the auth header. I've mocked everything up using Postman and it all works correctly. The issue is when I try to generate my own timestamp/nonce/signature in my class.
Here's the method from my class that sends the cURL request:
private function execute($options = array())
{
if (!isset($options['url'])) {
return;
}
$ch = curl_init($options['url']);
$method = (isset($options['method'])) ? $options['method'] : 'GET';
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
if (isset($options['auth']) && $options['auth']) {
$timestamp = round(microtime(true) * 1000);
$nonce = $this->getNonce(11);
$version = "1.0";
$signatureMethod = "HMAC-SHA1";
$signature = $this->generateSignature($options, $timestamp, $nonce, $signatureMethod, $version);
$authHeader = "Authorization: OAuth oauth_consumer_key=\"{$this->consumerKey}\",oauth_token=\"{$this->accessToken}\",oauth_signature_method=\"{$signatureMethod}\",oauth_timestamp=\"{$timestamp}\",oauth_nonce=\"{$nonce}\",oauth_version=\"{$version}\",oauth_signature=\"{$signature}\"";
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
$authHeader,
"Content-Type: application/json"
));
}
if (isset($options['body']) && !empty($options['body'])) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($options['body']));
}
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
The getNonce method I copied pretty much directly from https://github.com/BaglerIT/OAuthSimple/blob/master/src/OAuthSimple.php.
Here's the method I've written to generate the signature (which has been cobbled together from various SO posts and other sources):
protected function generateSignature($request, $timestamp, $nonce, $signatureMethod, $version)
{
$base = $request['method'] . "&" . rawurlencode($request['url']) . "&"
. rawurlencode("oauth_consumer_key=" . rawurlencode($this->consumerKey)
. "&oauth_nonce=" . rawurlencode($nonce)
. "&oauth_signature_method=" . rawurlencode($signatureMethod)
. "&oauth_timestamp=" . $timestamp
. "&oauth_version=" . $version);
$key = rawurlencode($this->consumerSecret) . '&' . rawurlencode($this->tokenSecret);
$signature = base64_encode(hash_hmac('sha1', $base, $key, true));
return $signature;
}
I can actually copy and paste the authorization header from Postman into my $authHeader variable, and replace everything except the timestamp/nonce/signature, and it works.
The response I'm getting from their server right now is [code] => 0005 but I can't find anything in their docs about response codes.
Edit: I had missed looking at the response header - the exact error is invalid signature.
There are 2 things I changed to get this to work.
I was missing the oauth_token when creating the base string for the signature
According to the OAuth Core 1.0 documentation, "Parameters are sorted by name, using lexicographical byte value ordering."
So I ended up re-ordering the parameters to be alphabetical. Here's what the code for generating the base string ended up looking like:
$base = $request['method'] . "&" . rawurlencode($request['url']) . "&"
. rawurlencode("oauth_consumer_key=" . rawurlencode($this->consumerKey)
. "&oauth_nonce=" . rawurlencode($nonce)
. "&oauth_signature_method=" . rawurlencode($signatureMethod)
. "&oauth_timestamp=" . rawurlencode($timestamp)
. "&oauth_token=" . rawurlencode($this->accessToken)
. "&oauth_version=" . rawurlencode($version));
I also re-ordered the params in the auth header to match the order of the base string:
$authHeader = "Authorization: OAuth oauth_consumer_key=\"{$this->consumerKey}\",oauth_nonce=\"{$nonce}\",oauth_signature_method=\"{$signatureMethod}\",oauth_timestamp=\"{$timestamp}\",oauth_token=\"{$this->accessToken}\",oauth_version=\"{$version}\",oauth_signature=\"{$signature}\"";
$base = $request['method']
. '&' . rawurlencode($request['url'])
. '&' . rawurlencode('oauth_consumer_key=' . $this->consumerKey)
. rawurlencode('&oauth_nonce=' . $nonce)
. rawurlencode('&oauth_signature_method=' . $signatureMethod)
. rawurlencode('&oauth_timestamp=' . $timestamp)
. rawurlencode('&oauth_version=' . $version)
. rawurlencode('&' . http_build_query($data));
$key = rawurlencode($this->consumerSecret) . '&';
$signature = rawurlencode(base64_encode(hash_hmac('SHA1', $base, $key, true)));
If you do a POST, make sure to include your posted data, otherwise the signature will not validate.
CURLOPT_HTTPHEADER => array(
"authorization: OAuth oauth_consumer_key=\"{$consumerKey}\",oauth_signature_method=\"{$signatureMethod}\",oauth_timestamp=\"{$timestamp}\",oauth_nonce=\"{$nonce}\",oauth_version=\"{$version}\",oauth_signature=\"{$oauthSignature}\"",
"content-type: application/x-www-form-urlencoded",
),
And the header should be as above
This fixed version worked for me :
function generateOauthSignature($method, $url, $consumerKey, $nonce, $signatureMethod, $timestamp, $version, $consumerSecret, $tokenSecret, $tokenValue, $extraParams = array())
{
$base = strtoupper($method) . "&" . rawurlencode($url) . "&"
. rawurlencode("oauth_consumer_key=" . $consumerKey
. "&oauth_nonce=" . $nonce
. "&oauth_signature_method=" . $signatureMethod
. "&oauth_timestamp=" . $timestamp
. "&oauth_token=" . $tokenValue
. "&oauth_version=" . $version);
if (!empty($extraParams)) {
$base .= rawurlencode("&" . http_build_query($extraParams));
}
$key = rawurlencode($consumerSecret) . '&' . rawurlencode($tokenSecret);
$signature = base64_encode(hash_hmac('sha1', $base, $key, true));
return rawurlencode($signature);
}
The following twitter thread helped me : https://twittercommunity.com/t/how-to-generate-oauth-signature-when-post-json-body-in-php/87581
I was also struggling with the proper setup of the OAuth 1 signature and had a lot of failed attempts. After TGA's hint to have a look how it's done with Twitter, I found out that there is an existing class which may be used out-of-the-box:
TwitterAPIExchange.php from the repository https://github.com/J7mbo/twitter-api-php.
Even if is called "Twitter...", it may also be used for other OAuth1 APIs. Calls will look like this:
$settings = array(
'oauth_access_token' => TOKEN,
'oauth_access_token_secret' => TOKEN_SECRET,
'consumer_key' => CONSUMER_KEY,
'consumer_secret' => CONSUMER_SECRET
);
$url = "https://api-url.com/api/v4/users/0451432/";
$requestMethod = 'POST';
$postfields = array(
'groupIds' => '23,24,25',
);
$twitter = new TwitterAPIExchange($settings);
return $twitter->buildOauth($url, $requestMethod)
->setPostfields($postfields)
->performRequest();
It works perfect for me.
This version matches the OAuth PECL library's function so you no longer need it.
public static function oauth_get_sbs(
$requestMethod,
$requestURL,
$request_parameters
): string
{
return $requestMethod . "&" . rawurlencode($requestURL) . "&"
. rawurlencode("oauth_consumer_key=" . rawurlencode($request_parameters['oauth_consumer_key'])
. "&oauth_nonce=" . rawurlencode($request_parameters['oauth_nonce'])
. "&oauth_signature_method=" . rawurlencode($request_parameters['oauth_signature_method'])
. "&oauth_timestamp=" . $request_parameters['oauth_timestamp']
. "&oauth_token=" . $request_parameters['oauth_token']
. "&oauth_version=" . $request_parameters['oauth_version']);
}
I am trying this sample code from this link. Currently, I can authorize but after i authorize the app, its showing me
Your session has timed out
What error is this actually? I tried searching in the internet but i couldnt found any solution for this. I just copied the full code and change the API key to my app API key.
This is my php code:
<?php
// Initiate the authorization process by sending a signed request to Twitter
// for a Request Token and then redirect the user to Twitter to authorize the
// application.
require "../include/oauthvalues.php";
session_start();
$oauthTimestamp = time();
$nonce = md5(mt_rand());
echo time();
// prepare the signature string
$sigBase = "GET&" . rawurlencode($requestTokenUrl) . "&"
. rawurlencode("oauth_consumer_key=" . rawurlencode($consumerKey)
. "&oauth_nonce=" . rawurlencode($nonce)
. "&oauth_signature_method=" . rawurlencode($oauthSignatureMethod)
. "&oauth_timestamp=" . $oauthTimestamp
. "&oauth_version=" . $oauthVersion);
// prepare the signature key
$sigKey = $consumerSecret . "&";
$oauthSig = base64_encode(hash_hmac("sha1", $sigBase, $sigKey, true));
// send the signed request and receive Twitter's response
$requestUrl = $requestTokenUrl . "?"
. "oauth_consumer_key=" . rawurlencode($consumerKey)
. "&oauth_nonce=" . rawurlencode($nonce)
. "&oauth_signature_method=" . rawurlencode($oauthSignatureMethod)
. "&oauth_timestamp=" . rawurlencode($oauthTimestamp)
. "&oauth_version=" . rawurlencode($oauthVersion)
. "&oauth_signature=" . rawurlencode($oauthSig);
$response = file_get_contents($requestUrl);
// extract and preserve the request tokens
parse_str($response, $values);
$_SESSION["requestToken"] = $values["oauth_token"];
$_SESSION["requestTokenSecret"] = $values["oauth_token_secret"];
// send the user to Twitter to grant authorization
$redirectUrl = $authorizeUrl . "?oauth_token=" . $_SESSION["requestToken"];
header("Location: " . $redirectUrl);
I am attempting to access the fat secret API.
https://platform.fatsecret.com/api/
I am attempting to create an Oauth signature using the secret key given by fat secret. When I try access the URL to grab the data I get an error saying my Oauth signature is invalid.
I create the signiture using base64_encode and then hash hmac using sha1.
Here is my code with the secret key blanked out, am I creating the signature in an incorrect way? Or can anyone see where I am going wrong.
Thank you
<?php
$requestTokenUrl = "http://platform.fatsecret.com/rest/server.api";
$oauth_consumer_key = "925f5e1a8b674a70b52eabf15f3265e7";
$nonce = md5(mt_rand());
$outh_signature = '';
$oauthSignatureMethod = "HMAC-SHA1";
$oauthTimestamp = time();
$oauthVersion = "1.0";
$secret_key = "My Secret Key";
$sigKey= $consumer_key . "&";
$sigBase = "method=food.get" . rawurlencode($requestTokenUrl) . "&"
. rawurlencode("oauth_consumer_key=" . rawurlencode($oauth_consumer_key)
. "&oauth_nonce=" . rawurlencode($nonce)
. "&oauth_signature_method=" . rawurlencode($oauthSignatureMethod)
. "&oauth_timestamp=" . $oauthTimestamp
. "&oauth_version=" . $oauthVersion);
$oauthSig = base64_encode(hash_hmac('sha1', $secret_key, true));
$requestUrl = $requestTokenUrl . "?"
. "food_id=33691"
. "&method=food.get"
. "&oauth_consumer_key=" . rawurlencode($oauth_consumer_key)
. "&oauth_nonce=" . rawurlencode($nonce)
. "&oauth_signature=" . rawurlencode($oauthSig)
. "&oauth_signature_method=" . rawurlencode($oauthSignatureMethod)
. "&oauth_timestamp=" . rawurlencode($oauthTimestamp)
. "&oauth_version=" . rawurlencode($oauthVersion);
var_dump($requestUrl);
Since Twitter API version 1.1 every request has to be authenticated and signed via OAuth 1.0a. In my PHP project I want to make use of the Twitter trends API, especially I want to use the GET trends/place call. So it's read-only.
Now, to authorize a request there's an excellent Twitter API documentation here. We learn that we have to send an additional header in the HTTP request, called "Authorization" that contains a string starting with "OAuth " and including seven parameters:
oauth_consumer_key
oauth_nonce
oauth_signature
oauth_signature_method
oauth_timestamp
oauth_token
oauth_version
Of those seven parameters the above mentioned third one, oauth_signature, is kind of special because to build its value you have to include all the other parameters plus more and then sign it. The process, again, is explained very well here.
I implemented all these steps after registering my app and getting consumer key & secret and access token & secret. Here's my PHP code (I crossed-out the secrets, of course):
$HTTPmethod = 'GET';
$twitterApiBaseUrl = 'https://api.twitter.com/1.1/trends/place.json';
$twitterApiParams = 'id=' . $WOEID;
$twitterApiCallUrl = $twitterApiBaseUrl . '?' . $twitterApiParams;
$OAuthConsumerKey = 'eV78fJOOiObfeytAwvWCg';
$OAuthAccessToken = '1116971396-6uc4xOLziLAdiqOfrtKfuRraa2GdCzas9aQX8ZB';
$OAConsumerSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$OATokenSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
// building the necessary (as of Twitter API v1.1) authorization header
// according to https://dev.twitter.com/docs/auth/authorizing-request
$DST = 'OAuth ';
// 1.: Consumer key
$oaConsumerKeyKey = rawurlencode("oauth_consumer_key");
$oaConsumerKeyVal = rawurlencode($OAuthConsumerKey);
$DST .= $oaConsumerKeyKey . '="' . $oaConsumerKeyVal . '", ';
// 2.: Nonce
$oaNonceKey = rawurlencode("oauth_nonce");
$oaNonceVal = rawurlencode(base64_encode(time()));
$DST .= $oaNonceKey . '="' . $oaNonceVal . '", ';
// 3.: Signature method
$oaSignatureMethodKey = rawurlencode("oauth_signature_method");
$oaSignatureMethodVal = rawurlencode('HMAC-SHA1');
$DST .= $oaSignatureMethodKey . '="' . $oaSignatureMethodVal . '", ';
// 4.: Timestamp
$oaTimestampKey = rawurlencode("oauth_timestamp");
$oaTimestampVal = rawurlencode(time());
$DST .= $oaTimestampKey . '="' . $oaTimestampVal . '", ';
// 5.: Token
$oaTokenKey = rawurlencode("oauth_token");
$oaTokenVal = rawurlencode($OAuthAccessToken);
$DST .= $oaTokenKey . '="' . $oaTokenVal . '", ';
// 6.: Version
$oaVersionKey = rawurlencode("oauth_version");
$oaVersionVal = rawurlencode('1.0');
$DST .= $oaVersionKey . '="' . $oaVersionVal . '", ';
// 7.: Signature
// according to https://dev.twitter.com/docs/auth/creating-signature
$preSignatureBaseString = $twitterApiParams;
$preSignatureBaseString .= '&';
$preSignatureBaseString .= $oaConsumerKeyKey . '=' . $oaConsumerKeyVal;
$preSignatureBaseString .= '&';
$preSignatureBaseString .= $oaNonceKey . '=' . $oaNonceVal;
$preSignatureBaseString .= '&';
$preSignatureBaseString .= $oaSignatureMethodKey . '=' . $oaSignatureMethodVal;
$preSignatureBaseString .= '&';
$preSignatureBaseString .= $oaTimestampKey . '=' . $oaTimestampVal;
$preSignatureBaseString .= '&';
$preSignatureBaseString .= $oaTokenKey . '=' . $oaTokenVal;
$preSignatureBaseString .= '&';
$preSignatureBaseString .= $oaVersionKey . '=' .$oaVersionVal;
print "<b>preSignatureBaseString:</b> $preSignatureBaseString<p/>\n";
$signatureBaseString = $HTTPmethod;
$signatureBaseString .= '&';
$signatureBaseString .= rawurlencode($twitterApiBaseUrl);
$signatureBaseString .= '&';
$signatureBaseString .= rawurlencode($preSignatureBaseString);
print "<b>signatureBaseString:</b> $signatureBaseString<p/>\n";
$signingKey = rawurlencode($OAConsumerSecret) . '&' . rawurlencode($OATokenSecret);
$oaSignatureKey = rawurlencode("oauth_signature");
$oaSignatureVal = base64_encode(hash_hmac('sha1', $signatureBaseString, $signingKey));
print "<b>oaSignatureVal:</b> $oaSignatureVal<p/>\n";
$DST .= $oaSignatureKey . '="' . rawurlencode($oaSignatureVal) . '"';
print "<b>DST:</b> $DST<p/>\n";
$header = "User-Agent: MyCoolTwitterTrendsApp\r\n" .
"Authorization: " . $DST . "\r\n";
$opts = array(
'http' => array(
'method' => $HTTPmethod,
'header' => $header
));
print "<b>header:</b> $header<p/>\n";
$context = stream_context_create($opts);
$twitterApiResponse = file_get_contents($twitterApiCallUrl, false, $context);
$decodedResponse = json_decode($twitterApiResponse);
echo $decodedResponse;
Problem is, the actual call to the API fails every time with an "HTTP/1.0 401 Unauthorized" error. Can anyone tell my why and what I'm doing wrong here?
Thank you so much!
Not sure if it's the same problem i have but try to check the timestamp mine was off exactly by 1 hour, go figure what that is!! daylite saving time
Use this code
$oauth_hash = '';
$oauth_hash .= 'oauth_consumer_key=YOUR_CONSUMER_KEY&';
$oauth_hash .= 'oauth_nonce=' . time() . '&';
$oauth_hash .= 'oauth_signature_method=HMAC-SHA1&';
$oauth_hash .= 'oauth_timestamp=' . time() . '&';
$oauth_hash .= 'oauth_token=YOUR_ACCESS_TOKEN&';
$oauth_hash .= 'oauth_version=1.0';
$base = '';
$base .= 'GET';
$base .= '&';
$base .= rawurlencode('https://api.twitter.com/1.1/trends/place.json');
$base .= '&';
$base .= rawurlencode('id=23424848&'.$oauth_hash);
$key = '';
$key .= rawurlencode('YOUR_CONSUMER_SECRET');
$key .= '&';
$key .= rawurlencode('YOUR_ACCESS_TOKEN_SECRET');
$signature = base64_encode(hash_hmac('sha1', $base, $key, true));
$signature = rawurlencode($signature);
$oauth_header = '';
$oauth_header .= 'oauth_consumer_key="YOUR_CONSUMER_KEY", ';
$oauth_header .= 'oauth_nonce="' . time() . '", ';
$oauth_header .= 'oauth_signature="' . $signature . '", ';
$oauth_header .= 'oauth_signature_method="HMAC-SHA1", ';
$oauth_header .= 'oauth_timestamp="' . time() . '", ';
$oauth_header .= 'oauth_token="YOUR_ACCESS_TOKEN", ';
$oauth_header .= 'oauth_version="1.0", ';
$curl_header = array("Authorization: Oauth {$oauth_header}", 'Expect:');
$curl_request = curl_init();
curl_setopt($curl_request, CURLOPT_HTTPHEADER, $curl_header);
curl_setopt($curl_request, CURLOPT_HEADER, false);
curl_setopt($curl_request, CURLOPT_URL, 'https://api.twitter.com/1.1/trends/place.json?id=23424848');
curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false);
var_dump(curl_exec($curl_request));
curl_close($curl_request);
I have Modified the code to get user timeline from this blog