401 on authorization


#1

The oauth authentication is failing only for our Production App. If we switch to a personal or development key it works perfectly

The error we are getting is:
401 Unauthorized

http header
[date] => Fri, 30 Sep 2011 23:47:33 GMT
[status] => 401 Unauthorized
[www_authenticate] => OAuth realm=“https://api.twitter.com
[x_transaction] => aea33f094c2a6ed0
[x_frame_options] => SAMEORIGIN
[last_modified] => Fri, 30 Sep 2011 23:47:33 GMT
[content_type] => text/html; charset=utf-8
[content_length] => 464
[pragma] => no-cache
[x_content_type_options] => nosniff
[x_revision] => DEV
[expires] => Tue, 31 Mar 1981 05:00:00 GMT
[cache_control] => no-cache, no-store, must-revalidate, pre-check=0, post-check=0

Anyone else?


#2

Using this code within PHP I get the same error.


HTTP/1.1 100 Continue HTTP/1.1 401 Unauthorized Date: Sat, 01 Oct 2011 09:55:53 GMT Status: 401 Unauthorized X-Transaction: d77d0f11137f00dd X-Frame-Options: SAMEORIGIN Last-Modified: Sat, 01 Oct 2011 09:55:53 GMT X-Runtime: 0.00828 Content-Type: text/html; charset=utf-8 Content-Length: 44 Pragma: no-cache X-Content-Type-Options: nosniff X-Revision: DEV Expires: Tue, 31 Mar 1981 05:00:00 GMT Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0 X-MID: cb5362513fa092c7e2aac8c800cc7d021dd130ce Set-Cookie: k=10.35.36.120.1317462953910162; path=/; expires=Sat, 08-Oct-11 09:55:53 GMT; domain=.twitter.com Set-Cookie: guest_id=v1%3A131746295391962890; domain=.twitter.com; path=/; expires=Mon, 30 Sep 2013 21:55:53 GMT Set-Cookie: _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCMBP6b4yAToHaWQiJTdlNGY5OTY4Y2Y5NjA3%250AYWVhMTg3NGRkMzM4MTIxNjJlIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA–efd3b7e43881e72a9e475b365d7ef39e4f6c8a9b; domain=.twitter.com; path=/; HttpOnly Vary: Accept-Encoding Server: tfe Failed to validate oauth signature and token

<?php class Twitter{ public static function getConsumerKey(){return '######';} public static function getConsumerSecret(){return '######';} static public function GenerateOauthNonce(){ $mt = microtime(); $rand = mt_rand(); return md5($mt . $rand); } static public function Authorize(){ $uri = 'http://api.twitter.com/oauth/request_token'; $params = Array(); $params['oauth_consumer_key'] = Twitter::getConsumerKey(); $params['oauth_nonce'] = Twitter::GenerateOauthNonce(); $params['oauth_signature_method'] = 'HMAC-SHA1'; $params['oauth_timestamp'] = time(); $params['oauth_version'] = "1.0"; foreach ($params as $k => $v){ $params[$k] = urldecode($v); } $uri = urldecode($uri); $BaseString = ''; foreach ($params as $k => $v){ $BaseString = $BaseString . '&' . $k . '=' . $v; } $BaseString = 'POST&' . $uri . urldecode($BaseString); echo $BaseString; $params['oauth_signature'] = base64_encode(hash_hmac('SHA1', $BaseString, Twitter::getConsumerSecret()."&", TRUE)); echo '
'; foreach ($params as $k => $v){ echo $k . '=>' .$v . '
'; } echo '
'; $session = curl_init($uri); curl_setopt ($session, CURLOPT_POST, true); curl_setopt ($session, CURLOPT_POSTFIELDS, $params); curl_setopt($session, CURLOPT_HEADER, true); curl_setopt($session, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($session); curl_close($session); return $response; } } ?>

#3

Is there any specific reason you’re writing your own OAuth implementation? I really urge you to consider using https://github.com/themattharris/tmhOAuth instead.

Some obvious issues:
Parameters need to be encoded before adding them to the signature base string:

$BaseString = ‘’;
foreach ($params as $k => $v){
$BaseString = $BaseString . ‘&’ . rawurlencode($k) . ‘=’ . rawurlencode($v);
}

The base string parts need to be encoded, and your BaseString composition has an extra leading “&” which needs to be stripped out:

$BaseString = ‘POST&’ . rawurlencode($uri) . ‘&’ . rawurlencode(substr($BaseString, 1));

CURLOPT_POSTFIELDS makes a mime/multipart request if you pass it an array, so you need to encode the parameters yourself:

curl_setopt ($session, CURLOPT_POSTFIELDS, http_build_query($params));

That’s probably enough to get a simple request working, but you’ll probably run into more issues for things like posting media uploads and such. It’s much, much easier to just use an existing OAuth library.


#4

@pixable, is the only difference the keys? or are you talking a production server vs. a development server? Also, which request are you failing on? Do any requests work?


#5

duvidas em todos os setores praticamente,Grata


#6

@kurrik …same I am also facing the same issue. I want to GET the Direct Messages .For this I have changed the Access Level to R/W n Direct Message . The time difference is within the permissible limit of 5 min . Or else even if I am using / hard-coding the Timestamp from Twitter I am getting this 401 error.
In case I am hard coding the values of timestamp as returned by twitter server then the Authorization Header is exactly the same .
Help find the mistake.


#7

@kurrik

When there are so many complicated steps involved, why does twitter not release an sdk and make it sensible to deal with it, instead of recommending to use external oauth libs?

Plus the mattharris lib is so poorly documented!