215: Bad Auth - Help?


#1

I’m trying to connect to the /1.1/lists/statuses.json API using PHP with curl. However, I don’t seem to be able to get the authorisation right.
What puzzles me is that the generated Authentication string via the OAuth tool doesn’t seem to work either.

Can anyone tell me what I’m doing wrong? Any help is much appreciated…

PHP code:

//REQUEST VARS
$type = 'GET';
$url = 'https://api.twitter.com/1.1/lists/statuses.json';
$params = Array(
            'list_id' => '92502794'
          );

//BUILDING THE REQUEST
$oauthparams = Array();
$oauthparams['oauth_consumer_key']      = $oauth_consumer_key;
$oauthparams['oauth_nonce']             = rand();
$oauthparams['oauth_signature_method']  = 'HMAC-SHA1';
$oauthparams['oauth_timestamp']         = time();
$oauthparams['oauth_token']             = $oauth_token;
$oauthparams['oauth_version']           = '1.0';


$allparams = Array();
$keys = Array();
foreach ($params as $key => $value) {
  $allparams[urlencode($key)] = urlencode($value);
}
foreach ($oauthparams as $key => $value) {
  $allparams[urlencode($key)] = urlencode($value);
}
ksort($allparams);
foreach( $allparams as $key => $value) {
  $signatureparam .= $key.'='.$value.'&';
}
$signatureparam = rtrim($signatureparam, "&");

$signaturebase = $type.'&'.urlencode($url).'&'.urlencode($signatureparam);

echo "<b>Signature base string:</b><br>".$signaturebase."<br><br>";

$signingkey = urlencode($oauth_consumer_secret).'&'.urlencode($oauth_access_token_secret);
$oauthparams['oauth_signature'] = base64_encode(hash_hmac('sha1',$signaturebase,$signingkey,true));

ksort($oauthparams);
$oauth = 'Authorisation: OAuth ';
foreach ($oauthparams as $key => $value) {
  $oauth .= urlencode($key).'="'.urlencode($value).'", ';
}
$oauth = rtrim($oauth, ", ");

echo "<b>Authorization header:</b><br>".$oauth."<br><br>";

$headers = Array('User-Agent: RSRClan twitter API',
                 'Content-Type: application/x-www-form-urlencoded; charset=utf-8',
                 $oauth);
$options = Array(CURLOPT_RETURNTRANSFER => TRUE, 
                 CURLOPT_BINARYTRANSFER => TRUE, 
                 CURLOPT_HTTPHEADER => $headers);

if ($params) {
  foreach ($params as $key => $value) {
    $paramstr .= '&'.$key.'='.$value;
  }
  $paramstr = '?'.ltrim($paramstr,'&');
}
else { $paramstr = ''; }

$request = curl_init($url.$paramstr);
curl_setopt_array($request, $options);
curl_setopt($request, CURLOPT_STDERR, fopen('php://output', 'w+'));
curl_setopt($request, CURLOPT_VERBOSE, 1);

echo "<pre>";

$data = curl_exec($request);

curl_close($request);
echo "</pre>";
echo $data;

The debug output is:

Signature base string:
GET&https%3A%2F%2Fapi.twitter.com%2F1.1%2Flists%2Fstatuses.json&list_id%3D92502794%26oauth_consumer_key%3DuJJqt8M2EU6n9f3WdYIg%26oauth_nonce%3D1038639869%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1373300539%26oauth_token%3D158464001-QfqU6w8963y89kI2D8LZmeraucaKvO9JT2Y0Tmbv%26oauth_version%3D1.0

Authorization header:
Authorisation: OAuth oauth_consumer_key="uJJqt8M2EU6n9f3WdYIg", oauth_nonce="1038639869", oauth_signature="OHSZAzRnmfrJla4Wq5c%2FgMSZNO0%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1373300539", oauth_token="158464001-QfqU6w8963y89kI2D8LZmeraucaKvO9JT2Y0Tmbv", oauth_version="1.0"

* Adding handle: conn: 0x2e8dc80
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 1 (0x2e8dc80) send_pipe: 1, recv_pipe: 0
* About to connect() to api.twitter.com port 443 (#1)
*   Trying 199.16.156.8...
* Connected to api.twitter.com (199.16.156.8) port 443 (#1)
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: none
* SSL connection using RC4-SHA
* Server certificate:
* 	 subject: C=US; ST=California; L=San Francisco; O=Twitter, Inc.; OU=Twitter Security; CN=api.twitter.com
* 	 start date: 2013-04-08 00:00:00 GMT
* 	 expire date: 2013-12-31 23:59:59 GMT
* 	 subjectAltName: api.twitter.com matched
* 	 issuer: C=US; O=VeriSign, Inc.; OU=VeriSign Trust Network; OU=Terms of use at https://www.verisign.com/rpa (c)09; CN=VeriSign Class 3 Secure Server CA - G2
* 	 SSL certificate verify ok.
> GET /1.1/lists/statuses.json?list_id=92502794 HTTP/1.1
Host: api.twitter.com
Accept: */*
User-Agent: RSRClan twitter API
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Authorisation: OAuth oauth_consumer_key="uJJqt8M2EU6n9f3WdYIg", oauth_nonce="1038639869", oauth_signature="OHSZAzRnmfrJla4Wq5c%2FgMSZNO0%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1373300539", oauth_token="158464001-QfqU6w8963y89kI2D8LZmeraucaKvO9JT2Y0Tmbv", oauth_version="1.0"

< HTTP/1.1 400 Bad Request
< content-length: 61
< content-type: application/json; charset=utf-8
< date: Mon, 08 Jul 2013 16:21:34 UTC
* Server tfe is not blacklisted
< server: tfe
< set-cookie: guest_id=v1%3A137330049421272065; Domain=.twitter.com; Path=/; Expires=Wed, 08-Jul-2015 16:21:34 UTC
< strict-transport-security: max-age=631138519
< 
* Connection #1 to host api.twitter.com left intact
{"errors":[{"message":"Bad Authentication data","code":215}]}

#2

I noticed in your curl debug that you have the header called “Authorisation” instead of “Authorization” – that’s possibly your issue. Though it likely is not related, you’re also setting a Content-Type on a GET request, which isn’t necessary (as you’re not providing a content body on a GET request).


#3

Argh, if this boils down to that one typo I’m gonna have a major facepalm…
checking…

Yup. It’s working now.

Episod, thanks a lot :stuck_out_tongue: Sorry! haha.