문제

I have set up OAuth and I am using CURL to get the latest tweet, this works perfectly when I run it from my browser

http://mydomain.com/getstatus.php

The script write statuses into a file:

$xTIME = time();
$oauth = array(
  'oauth_consumer_key'     => $consumer_key,
  'oauth_nonce'            => $xTIME,
  'oauth_signature_method' => 'HMAC-SHA1',
  'oauth_token'            => $oauth_access_token,
  'oauth_timestamp'        => $xTIME,
  'oauth_version'          => '1.0'
);

$base_info                = buildBaseString($url, 'GET', $oauth);
$composite_key            = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
$oauth_signature          = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;

$header = array(buildAuthorizationHeader($oauth), 'Expect:');
$options = array(
  CURLOPT_HTTPHEADER     => $header,
  CURLOPT_HEADER         => false,
  CURLOPT_URL            => $url,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_SSL_VERIFYPEER => false
);

$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);

$twitter_data = json_decode($json); 

if(isset($twitter_data[0]->text))
{
  $fp = fopen('/var/www/mydomain.com/feeds/twitter.feed', 'w');
  fwrite($fp, $twitter_data[0]->text);
  fclose($fp);
}

This writes to the file nicely, the idea is to have this run every hour.

So I set up a cronjob

0 * * * * lynx -accept_all_cookies http://mydomain.com/getstatus.php

But I get this returned:

[request] => /1/statuses/user_timeline.json?count=1&screen_name=twitter
[error] => Rate limit exceeded. Clients may not make more than 150 requests per hour.

Which suggests it is not authorizing and so treating the request as an unauth'd request.

My question is, why would it not be authorizing?

I have tried running it as a crontab and running it through lynx and I get the same outcome both times.

Edit:

Here are the full functions,

function buildBaseString($baseURI, $method, $params)
{
    $r = array(); 
    ksort($params);
    foreach($params as $key=>$value){
        $r[] = "$key=" . rawurlencode($value); 
    }
    return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r)); 
}

function buildAuthorizationHeader($oauth)
{
    $r = 'Authorization: OAuth '; 
    $values = array(); 
    foreach($oauth as $key=>$value)
        $values[] = "$key=\"" . rawurlencode($value) . "\""; 
    $r .= implode(', ', $values); 
    return $r; 
}

function loadTW($twID)
{
    $url = "https://api.twitter.com/1/statuses/user_timeline.json&count=1&screen_name=" .$twID;

    $oauth_access_token = "68161130-X4HRZje9wB3lpyeOPYDJPsqG1JfJxxxxxxxx";
    $oauth_access_token_secret = "zN98CUldHN4eiVeGahZIvpNeUGljRTxxxxxxxx";
    $consumer_key = "PeVEz2Z0QSKtxxxxxxx";
    $consumer_secret = "An9Xh3qHHTEiTQzW5wKLFMHOrbzwFtwxxxxxxxx";

    $xTIME = time();
    $oauth = array( 'oauth_consumer_key' => $consumer_key,
                    'oauth_nonce' => $xTIME,
                    'oauth_signature_method' => 'HMAC-SHA1',
                    'oauth_token' => $oauth_access_token,
                    'oauth_timestamp' => $xTIME,
                    'oauth_version' => '1.0');  


    $base_info = buildBaseString($url, 'GET', $oauth);

    $composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);

    $oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));

    $oauth['oauth_signature'] = $oauth_signature;                       

    $header = array(buildAuthorizationHeader($oauth), 'Expect:');
    $options = array( CURLOPT_HTTPHEADER => $header,
                      CURLOPT_HEADER => false,
                      CURLOPT_URL => $url,
                      CURLOPT_RETURNTRANSFER => true,
                      CURLOPT_SSL_VERIFYPEER => false);

    $feed = curl_init();
    curl_setopt_array($feed, $options);
    $json = curl_exec($feed);
    curl_close($feed);

    $twitter_data = json_decode($json); 

    if(isset($twitter_data[0]->text))
    {
        $fp = fopen('/var/www/carlandalexfishing.co.uk/feeds/twitter.feed', 'w');
        fwrite($fp, $twitter_data[0]->text);
        fclose($fp);
    }
}
도움이 되었습니까?

해결책

It's pretty hard to know what's going on in your code, as it's not the full code. Anyway :

  • Your OAuth code only signs the oauth_* headers, not any query arguments.
  • Your $url variable seems to contain query parameters as well, judging by the error message.

To solve this, just move the query parameters into a separate array and sign the OAuth request with them.


Illustration of what's going wrong (intentionally left out url encoding and added spaces):

GET & https://api.twitter.com/1/endpoint.json?count=1&screen_name=twitter & oauth_abc=def&oauth_ghi=jkl

The query part of the URL shouldn't go in the second part of the OAuth base string. Better :

GET & https://api.twitter.com/1/endpoint.json & count=1&oauth_abc=def&oauth_ghi=jkl&screen_name=twitter
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top