Oauth/request_token resource documentation contradiction and issue



I’m trying hard to get a twitter request token work, but failed even that I compare 1:1 the signatures generated by Twitter to mine. I also found that the signature generator output is conflicting with the API documentation.

I tried:

  • My method works well for GET queries.
  • Twitter doc says to send oauth_consumer_key without oauth_token - I sent both to make sure (the Twitter signature tool DOES send the oauth_token for this resource).
  • I synched my server time with the twitter UNIX time. It worked well for GET, so most likely the issue is not there.
  • I tried to chain the oauth variables with different types of sorts, however - in the end I fit it exactly to the output of the signature generator.
  • I compared both the signature generated by the signature generator AND the header - they matched 1:1 to what my code has generated (I did it by synching my clock 20 sec to the future, hard coded the oauth_nonce that twitter generated into my code, and let the script run exactly on Twitter’s unix time). Still - I got the same error.
  • I tried to post the argument as POST data (even that documentation says not to, to make sure there is not error there)
  • I tried to move the oauth_callback into the $oauth array so it would be coded with the signature, AND to send it as a POST argument (again, because it is not clear from the documentation how to send it)
  • I tried to omit the header prefix “Authorization:” since in the resource doc, the example code omitted it. However this gained no API response.

Does anyone have clues? I attach the code and the header comparison between Twitter and my code

It looks like the Twitter documentation is contradicting itself, so I tried several options and still failed:

include 'global_variables.php'; // this is where the twitter app id and secret are defined
function add_quotes($str) 
	return '"'.$str.'"'; 

$method = 'POST';
$resource_url = '/oauth/request_token'; 
$args['oauth_callback'] = 'http%3A%2F%2Fwww.my-website.com'; // as defined in Twitter App page. I tried this inside the $oauth array as well

$oauth = array(
	'oauth_nonce' => 'f114fd6a0bccc391430b6fd2113276fe',	
	'oauth_signature_method' => 'HMAC-SHA1',
	'oauth_timestamp' => time()+25320,
    'oauth_consumer_key' => $G_twitter_app_id,
	'oauth_token' => $G_twitter_access_token,
    'oauth_version' => '1.0'
// time + 25320 is synching my server time with Twitter UTC time. With GET it works perfectly (server is overwriting my ragional time setup)
$url = "https://api.twitter.com".$resource_url;
$combined_args = $oauth; 
$querystring = urldecode(http_build_query($combined_args, '', '&'));

$base_string = $method."&".rawurlencode($url)."&".rawurlencode(urldecode(http_build_query($args, '', '&')))."%26".rawurlencode($querystring);
$key = rawurlencode($G_twitter_app_secret)."&".rawurlencode($G_twitter_access_token_secret);
echo $base_string."<br>-----------<br>";
$oauth['oauth_signature'] = rawurlencode(base64_encode(hash_hmac('sha1', $base_string, $key, true)));
ksort($oauth); // probably not necessary, but twitter's demo does it
$oauth = array_map("add_quotes", $oauth);
$auth = array();
$auth['0'] = "Authorization: OAuth " . urldecode(http_build_query($oauth, '', ', ')); // this is the full value of the Authorization line
echo $auth['0']."<br>-----------<br>";
$response = curl_init();
curl_setopt($response, CURLOPT_HTTPHEADER, $auth);
curl_setopt($response, CURLOPT_HEADER, false);                
curl_setopt($response, CURLOPT_URL, $url);                
curl_setopt($response, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($response, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($ch, CURLOPT_POST, count($args)); // I tried with and without it
//curl_setopt($response, CURLOPT_POSTFIELDS, $args); // I tried with and without it

$json = curl_exec($response);
$twitter_data = json_decode($json,true);



Authorization: OAuth oauth_consumer_key=“EXACTLYTHESAME”,
oauth_signature_method=“HMAC-SHA1”, oauth_timestamp=“1442974996”,
oauth_token=“EXACTLYTHESAME”, oauth_version=“1.0”