request_token 400 response


#1

For the life of me I can’t figure out why this isn’t working. The Authorization header seams fine, but for some reason it won’t work. Below is an example.

Base String:
POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_callback%3Dhttp%253A%252F%252Flocalhost%252Fdev%252F%26oauth_consumer_key%3DRFr6U9avTvMIqe8AIlbJxw%26oauth_nonce%3D4bee9a52f517fb244406e9a8253ed440%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1362692958%26oauth_version%3D1.0

Signature:
+dtkMt7QD0cv+kGaEGrqYhOe15Q=

Authorization Header:
Authorization: OAuth oauth_callback=“http%3A%2F%2Flocalhost%2Fdev%2F”, oauth_consumer_key=“RFr6U9avTvMIqe8AIlbJxw”, oauth_nonce=“4bee9a52f517fb244406e9a8253ed440”, oauth_signature_method=“HMAC-SHA1”, oauth_timestamp=“1362692958”, oauth_version=“1.0”, oauth_signature="%2BdtkMt7QD0cv%2BkGaEGrqYhOe15Q%3D"

Request:
array
’oauth_callback’ => string ‘http://localhost/dev/’ (length=21)
‘oauth_consumer_key’ => string ‘RFr6U9avTvMIqe8AIlbJxw’ (length=22)
‘oauth_nonce’ => string ‘4bee9a52f517fb244406e9a8253ed440’ (length=32)
‘oauth_signature_method’ => string ‘HMAC-SHA1’ (length=9)
‘oauth_timestamp’ => int 1362692958
’oauth_version’ => string ‘1.0’ (length=3)
‘oauth_signature’ => string ‘+dtkMt7QD0cv+kGaEGrqYhOe15Q=’ (length=28)

Response:
array
’http_code’ => int 400
’results’ => string ‘’ (length=0)
‘error’ => string ‘’ (length=0)
‘headers’ =>
array
’Content-Length’ => string ‘0’ (length=1)
‘Connection’ => string ‘close’ (length=5)

Anyone have any idea what’s going on? I’m constructing this manually and performing the request with CURL. I do not want to use a 3rd party library which has too much potential to conflict with other installed items.


#2

If at all possible, could you capture the full request-and-response cycle, complete with HTTP headers both ways? I’d like to track this down.


#3

That is the full request and response from CURL. Below is the usage.

$ch = curl_init();
		curl_setopt( $ch, CURLOPT_URL, $url );

		if ( $method == 'POST' ) {
			curl_setopt( $ch, CURLOPT_POST, true );
		}

		if ( $body ) {
			if ( $method == 'POST' ) {
				curl_setopt( $ch, CURLOPT_POSTFIELDS, $body );
			} else {
				curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query( $body, null, '&' ) );
			}
		}

		if ( $headers ) {
			curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
		} else {
			curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'Expect:' ) );
		}

		curl_setopt( $ch, CURLOPT_TIMEOUT, 30 );
		curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );

		if ( ( ! ini_get( 'safe_mode' ) ) && ( ! ini_get( 'open_basedir' ) ) ) {
			curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1 );
		}

		curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
		curl_setopt( $ch, CURLOPT_HEADER, true );

		if ( $plugin->params->get( 'global_curl_ipv4', 1 ) ) {
			if ( version_compare( phpversion(), '5.3.0', '>=' ) ) {
				$curlVersion							=	curl_version();

				if ( isset( $curlVersion['version'] ) && version_compare( $curlVersion['version'], '7.10.8', '>=' ) ) {
					curl_setopt( $ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
				}
			}
		}

		$result											=	curl_exec( $ch );
		$httpCode										=	curl_getinfo( $ch, CURLINFO_HTTP_CODE );
		$error											=	curl_error( $ch );

		if ( $result ) {
			list( $rawResponseHeaders, $results )		=	explode( "\r\n\r\n", $result, 2 );
		} else {
			$rawResponseHeaders							=	null;
			$results									=	null;
		}

		$responseHeaders								=	array();

		if ( $rawResponseHeaders ) {
			$responseHeaderLines						=	explode( "\r\n", $rawResponseHeaders );

			array_shift( $responseHeaderLines );

			foreach ( $responseHeaderLines as $headerLine ) {
				list( $header, $value )					=	explode( ': ', $headerLine, 2 );

				if ( isset( $responseHeaders[$header] ) ) {
					$responseHeaders[$header]			.=	"\n" . $value;
				} else {
					$responseHeaders[$header]			=	$value;
				}
			}
		}

		curl_close( $ch );

		$response										=	array(	'http_code' => $httpCode,
																	'results' => $results,
																	'error' => $error,
																	'headers' => $responseHeaders
																);

#4

Are you able to get to the command line of the machine and is this happening for you on all requests to this method?

If so, can you capture the results of this command (or something similar to it)?

curl -X POST “https://api.twitter.com/oauth/request_token” --verbose


#5

I’ve no experience with command line usage, I’m on windows using a localhost. Yes, this happens on all requests. Even an empty request like the one supplied gives the same results. If I add the request to the POST instead of Authorization header I get the following though.

array
’http_code’ => int 401
’results’ => string ‘Failed to validate oauth signature and token’ (length=44)
‘error’ => string ‘’ (length=0)
‘headers’ =>
array
’Date’ => string ‘Thu, 07 Mar 2013 23:15:53 GMT’ (length=29)
‘Status’ => string ‘401 Unauthorized’ (length=16)
‘Last-Modified’ => string ‘Thu, 07 Mar 2013 23:15:53 GMT’ (length=29)
‘X-Transaction’ => string ‘2a0b29fb006881e4’ (length=16)
‘Content-Length’ => string ‘44’ (length=2)
‘Content-Type’ => string ‘text/html; charset=utf-8’ (length=24)
‘X-Runtime’ => string ‘0.01522’ (length=7)
‘X-Frame-Options’ => string ‘SAMEORIGIN’ (length=10)
‘Cache-Control’ => string ‘no-cache, no-store, must-revalidate, pre-check=0, post-check=0’ (length=62)
‘Expires’ => string ‘Tue, 31 Mar 1981 05:00:00 GMT’ (length=29)
‘X-MID’ => string ‘3d87b1693029846121e1fd8e85628b765c5c0064’ (length=40)
‘Pragma’ => string ‘no-cache’ (length=8)
‘Set-Cookie’ => string ‘k=10.40.51.134.1362698153859227; path=/; expires=Thu, 14-Mar-13 23:15:53 GMT; domain=.twitter.com
_twitter_sess=BAh7CCIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%250ASGFzaHsABjoKQHVzZWR7ADoPY3JlYXRlZF9hdGwrCIyvI0c9AToHaWQiJTNh%250ANWY1NTc1NzA5OTExYTEzNWIyZjdjOGFhMjdiNjdk–513999226b8d819bb6d7bb90489b63f307c4495d; domain=.twitter.com; path=/; HttpOnly
guest_id=v1%3A136269815372737074; Domain=.twitter.com; Path=/; Expires=Sat, 07-Mar-2015 23:15:53 UTC’ (length=464)
‘Vary’ => string ‘Accept-Encoding’ (length=15)
‘Server’ => string ‘tfe’ (length=3)


#6

Success! I had to send ‘Content-length: 0’ with the header for it to work. Once added I received 200 response with the token… phew what a pain… hopefully documentation could be improved to include a working PHP example?


#7

same here, been struggling with it a lot, thanks for tip kyle.