Php 从crontab运行时未授权Twitter API

Php 从crontab运行时未授权Twitter API,php,curl,twitter-oauth,crontab,lynx,Php,Curl,Twitter Oauth,Crontab,Lynx,我已经设置了OAuth,我正在使用CURL来获取最新的tweet,当我从浏览器运行它时,它可以完美地工作 http://mydomain.com/getstatus.php 脚本将状态写入文件: $xTIME = time(); $oauth = array( 'oauth_consumer_key' => $consumer_key, 'oauth_nonce' => $xTIME, 'oauth_signature_method' =&

我已经设置了OAuth,我正在使用CURL来获取最新的tweet,当我从浏览器运行它时,它可以完美地工作

http://mydomain.com/getstatus.php
脚本将状态写入文件:

$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);
}
这会很好地写入文件,其想法是每小时运行一次

所以我找了份工作

0 * * * * lynx -accept_all_cookies http://mydomain.com/getstatus.php
但我得到的回报是:

[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.
这表明它没有授权,因此将该请求视为未经批准的请求

我的问题是,为什么不授权

我试着将它作为crontab运行,并通过lynx运行,两次都得到了相同的结果

编辑:

以下是全部功能

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);
    }
}

很难知道代码中发生了什么,因为它不是完整的代码。无论如何:

  • OAuth代码只对OAuth_*头进行签名,而不是对任何查询参数进行签名
  • 根据错误消息判断,
    $url
    变量似乎也包含查询参数
要解决这个问题,只需将查询参数移动到一个单独的数组中,并用它们对OAuth请求进行签名


错误说明(故意省略url编码并添加空格):

URL的查询部分不应该放在OAuth基字符串的第二部分。更好:

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

我们可以看看
buildBaseString
&
buildAuthorizationHeader
函数的代码,以及
$url
中的内容吗?wget是否给出了相同的消息?我已经添加了其余的完整函数,我只是尝试了wget,但它没有更新twitter提要。我想我明白你的意思了,但我很挣扎,因为我通常不使用卷曲。你能给我举个例子,告诉我如何设置你告诉我要更改的位吗?这与cURL的用法无关。不,我相信上面的例子就足够了。太好了!非常感谢,我将它添加到
$oauth=array()
中,但它仍然没有进行身份验证,所以我也在这里添加了它,它工作得非常好?屏幕名称='$小树枝。”&count=1',谢谢您的回答
GET & https://api.twitter.com/1/endpoint.json & count=1&oauth_abc=def&oauth_ghi=jkl&screen_name=twitter