another twitter oAuth cURL access token request that fails
Below is what Ive put together so far and it works :-)
class Twitauth
{
var $key = '';
var $secret = '';
var $request_token = "https://twitter.com/oauth/request_token";
function Twitauth($config)
{
$this->key = $config['key']; // consumer key from twitter
$this->secret = $config['secret']; // secret from twitter
}
function getRequestToken()
{
// Default params
$params = array(
"oauth_version" => "1.0",
"oauth_nonce" => time(),
"oauth_timestamp" => time(),
"oauth_consumer_key" => $this->key,
"oauth_signature_method" => "HMAC-SHA1"
);
// BUILD SIGNATURE
// encode params keys, values, join and then sort.
$keys = $this->_urlencode_rfc3986(array_keys($params));
$values = $this->_urlencode_rfc3986(array_values($params));
$params = array_combine($keys, $values);
uksort($params, 'strcmp');
// convert params to string
foreach ($params as $k => $v) {$pairs[] = $this->_urlencode_rfc3986($k).'='.$this->_urlencode_rfc3986($v);}
$concatenatedParams = implode('&', $pairs);
// form base string (first key)
$baseString= "GET&".$this->_urlencode_rfc3986($this->request_token)."&".$this->_urlencode_rfc3986($concatenatedParams);
// form secret (second key)
$secret = $this->_urlencode_rfc3986($this->secret)."&";
// make signature and append to params
$params['oauth_signature'] = $this->_urlencode_rfc3986(base64_encode(hash_hmac('sha1', $baseString, $secret, TRUE)));
// BUILD URL
// Resort
uksort($params, 'strcmp');
// convert params to string
foreach ($params as $k => $v) {$urlPairs[] = $k."=".$v;}
$concatenatedUrlParams = implode('&', $urlPairs);
// form url
$url = $this->request_token."?".$concatenatedUrlParams;
// Send to cURL
print $this->_http($url);
}
function _http($url, $post_data = null)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
if(isset($post_data))
{
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}
$response = curl_exec($ch);
$this->http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$this->last_api_call = $url;
curl_close($ch);
return $response;
}
function _urlencode_rfc3986($input)
{
if (is_array($input)) {
return array_map(array('Twitauth', '_urlencode_rfc3986'), $input);
}
else if (is_scalar($input)) {
return str_replace('+',' ',str_replace('%7E', '~', rawurlencode($input)));
}
else{
return '';
}
}
}
Twitter API - Failed to validate oauth signature and token PHP / CURL
Your problem is that you did not include the OAuth signature in your request.
You can read about the concept on this page.
A working implementation can be found here.
Twitter request token OAuth 401 error
For anyone else facing this issue, I am listing down few things that you could benefit from.
After excruciating attempts of permutations and combinations,
oauth_token
had to be a part of the signature (even if its value is
empty string).
I am not sure if it is mentioned anywhere and particularly ironic that you had to remove access token and secret while using Twitter's OAuth testing tool (for the Curl command to work properly which took some bloody lot of time to figure out.)
It is good to validate your basestring - Tool
Validating if your signature process is correct - Check point (f)
Twitter API oAuth failed signature when adding callback url
I solved the issue. The problem was that even though the callback URL was sent correctly using the querystring method or headers as you can see on the links, it was also double escaped when creating the signature from the basestring. Since the documentation is pretty bad regarding this I didn't think that you shouldn't double escape it as well like other oauth_* parameters (aka percentage encode the "&"s).
Twitter Oauth Lib.... another once
It seems like you are trying to force your oauth parameters like a token.
You need to build an "Authorization" header, and send it to twitter for a request token. I've destroyed your code's class functionality, but as a single php file, it works fine.
Check out the differences, and try to embed them into your own class.
Here is the code:
<?php
getRequestToken ();
function signRequest($secret, $baseString) {
return base64_encode ( hash_hmac ( 'sha1', $baseString, $secret, TRUE ) );
}
function getRequestToken() {
$urlParams = array (
"oauth_consumer_key" => "5P7F5qtIUujg3KtLxxxxxx", //$this->consumer_key,
"oauth_signature_method" => "HMAC-SHA1", //$this->oauth_signature_method,
"oauth_timestamp" => time(),
"oauth_nonce" => md5 ( uniqid ( rand(), true ) ), // don't use time for nonce :)
"oauth_version" => "1.0" //$this->oauth_version
);
ksort ( $urlParams ); // don't need uksort, ksort is enough
foreach ( $urlParams as $k => $v ) {
$joinedParams [] = $k . "=" . $v;
}
$joinedParams = implode ( "&", $joinedParams );
$baseString = "GET&" . rawurlencode ( "https://api.twitter.com/oauth/request_token" ) . "&" . rawurlencode ( $joinedParams );
$secret = rawurlencode ( "3q017y6ir8Rxxxxxxx" ) . "&"; //$this->consumer_secret."&";
// We need to use the $baseString, not an url
$urlParams ['oauth_signature'] = rawurlencode ( signRequest ( $secret, $baseString ) );
// Another ksort is not needed, it is ok for signature to be at the end, however:
ksort($urlParams);
// We need to build an array of headers for CURL
$urlParts = parse_url ( "https://api.twitter.com/oauth/request_token" );
$header = array ('Expect:' );
$oauthHeader = 'Authorization: OAuth realm="' . $urlParts ['path'] . '", ';
foreach ( $urlParams as $name => $value ) {
$oauthHeader .= "{$name}=\"{$value}\", ";
}
$header [] = substr ( $oauthHeader, 0, - 2 );
// Ask Twitter for a request token
$ch = curl_init ( "https://api.twitter.com/oauth/request_token" );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $header );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, false );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false );
$content = curl_exec ( $ch );
curl_close ( $ch );
// Create the url from the curl answer
parse_str($content, $output);
$url = "https://api.twitter.com/oauth/authorize?oauth_token=" . $output["oauth_token"];
echo $url ;
}
Related Topics
Php.Exe' Is Not Recognized as an Internal or External Command, Operable Program or Batch File
Comment Associative Array in PHP Documentor
Preg Match Text in PHP Between HTML Tags
How to Re-Format Datetime String in PHP
Debug a Domdocument Object in PHP
Explode a String to Associative Array Without Using Loops
Simple HTML Dom File_Get_HTML Not Working - Is There Any Workaround
Laravel Eloquent, Group by Month/Year
Cannot Use String Offset as an Array in PHP
How to Regex-Replace Multiple <Br /> Tags with One <Br /> Tag
Check If Specific Input File Is Empty
When Do I Have to Declare Session_Start();
How to Embed Images in a Single HTML/PHP File
"PHP Fatal Error: Class 'Httprequest' Not Found"
PHP Multipart Form Data Put Request
How to Populate Dependable Drop-Down Using Ajax and PHP
Codeigniter Default Controller in a Sub Directory Not Working