【问题标题】:Authorizing with oAuth, posting to Twitter使用 oAuth 进行授权,发布到 Twitter
【发布时间】:2013-03-14 09:25:46
【问题描述】:

我创建了一个 Twitter 应用程序来自动发布到我的 Twitter 帐户。所以,我不需要授权新用户。

我已经将访问级别设置为读/写,并收到了访问令牌。我在应用程序中使用了 OAuth 工具来生成 cURL 命令:

curl --request 'POST' 'https://api.twitter.com/1/statuses/update.json' --data 'status=Maybe+he%27ll+finally+find+his+keys.+%23peterfalk' --header '授权:OAuth oauth_consumer_key="...", oauth_nonce="97fad626790e8e5988d4a06cfd47fa74", oauth_signature=".. .", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1364161424", oauth_token="...", oauth_version="1.0"' --verbose

命令上面写着:

重要提示:这只会在几分钟内有效。还记得 cURL 命令将实际执行请求。

我认为这将在 linux 终端中运行。

我想知道如何将其转换为 PHP cURL 命令。这是我尝试过的。注意$DST 的值是https://dev.twitter.com/docs/auth/authorizing-request 中“DST”的值;也等于OAuth工具中cURL命令中--header 'Authorization:后面字符串的值。

$ch = curl_init();
curl_setopt_array($ch, array(
    CURLOPT_RETURNTRANSFER => 1,
    CURLOPT_URL => $url,
    CURLOPT_POST => 1,
    CURLOPT_POSTFIELDS => array(
        data => 'status='.urlencode($status),
        header => 'Authorization: '.$DST
    )
));
$resp = curl_exec($ch);
curl_close($ch);

但是$resp的值是:

{
request: "/1/statuses/update.json",
error: "Could not authenticate you."
}

我做错了什么吗?请注意,OAuth 工具表示 cURL 命令实际上可以工作。所以我认为这只是弄清楚如何在 PHP 中排列 cURL 的问题。我对它不是很熟悉。另请注意,如果可以,我想避免使用 OAuth 库。我觉得应该有一个比安装整个库更轻量级的解决方案。

【问题讨论】:

    标签: php curl twitter twitter-oauth


    【解决方案1】:

    我遇到了三个问题:

    (1) 我没有在这个问题中包含它,但我的签名没有正确创建。

    我所做的是 base64_encode(hash_hmac('sha1', $base, $key)); 但我应该将 hash_hmac 第四个参数设置为 true 以返回原始二进制而不是十六进制(十六进制显示为 Twitter 文档中的示例,这就是让我困惑)。因此正确的函数是:base64_encode(hash_hmac('sha1', $base, $key, true));

    (2) cURL 设置不正确。我需要 CURLOPT_HTTPHEADER 来设置授权,并且 CURL_VERBOSE 设置为 true:

    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: ' . $DST));
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, 'status='.rawurlencode($status));
    curl_setopt($ch, CURLOPT_URL, $url);
    

    (3) 如上面的代码所示,我必须将状态发布为字符串,而不是数组。我在这个问题上找到了解决这个问题的方法:Why can't I authenticate with OAuth?

    所有这些现在都运行良好。此外,请确保您的 Twitter 应用程序中的访问令牌表明访问级别为“读写”。如果没有,请在“设置”中更改权限,然后返回“详细信息”并重新创建您的访问令牌。

    完整脚本

    <?php
    
    class Tweet {
    
    public $url = 'https://api.twitter.com/1/statuses/update.json';
    
    function the_nonce(){
        $nonce = base64_encode(uniqid());
        $nonce = preg_replace('~[\W]~','',$nonce);
        return $nonce;
    }
    
    function get_DST($status){
    
        $url = $this->url;
    
        $consumer_key = $your_consumer_key_here;
        $nonce = $this->the_nonce();
        $sig_method = 'HMAC-SHA1';
        $timestamp = time();
        $version = "1.0";
        $token = $your_token_here;
        $access_secret = $your_access_secret_here;
        $consumer_secret = $your_consumer_secret_here;
    
        $param_string = 'oauth_consumer_key='.$consumer_key.
                '&oauth_nonce='.$nonce.
                '&oauth_signature_method='.$sig_method.
                '&oauth_timestamp='.$timestamp.
                '&oauth_token='.$token.
                '&oauth_version='.$version.
                '&status='.rawurlencode($status);
        $sig_base_string = 'POST&'.rawurlencode($url).'&'.rawurlencode($param_string);
        $sig_key = rawurlencode($consumer_secret).'&'.rawurlencode($access_secret);
    
        $tweet_sig = base64_encode(hash_hmac('sha1', $sig_base_string, $sig_key, true));
    
        $DST = 'OAuth oauth_consumer_key="'.rawurlencode($consumer_key).'",'.
            'oauth_nonce="'.rawurlencode($nonce).'",'.
            'oauth_signature="'.rawurlencode($tweet_sig).'",'.
            'oauth_signature_method="HMAC-SHA1",'.
            'oauth_timestamp="'.rawurlencode($timestamp).'",'.
            'oauth_token="'.rawurlencode($token).'",'.
            'oauth_version="1.0"';
        return $DST;
    }
    
    function set($status){
    
        $url = $this->url;
    
        $ch = curl_init();
    
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: ' . $this->get_DST($status)));
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, 'status='.rawurlencode($status));
    curl_setopt($ch, CURLOPT_URL, $url);
    
        $result = json_decode(curl_exec($ch));
    if(!curl_errno($ch)){
        $info = curl_getinfo($ch);
        if($info['http_code']!='200'){
    //error posting
    echo 'Error: '.$result->{'error'};
        }else{
    //success
    echo 'Success! <a href="https://twitter.com/AOKHalifax/status/'.$result->{'id_str'}.'" target="_blank">View Tweet</a>';
        }
    }else{
        //error connecting
        echo 'error posting';
        }
        curl_close($ch);
        }
    }
    
    /* 
    Usage example:
    $status = new Tweet();
    $status->set('checking'); 
    */
    
    ?>
    

    【讨论】:

    • 感谢分享代码!您知道如何将图像与状态消息一起发布到 Twitter 吗?新年快乐
    • 你拯救了我的一天。感谢分享解决方案。
    【解决方案2】:

    您好,感谢您的帮助。

    我遇到了同样的问题,你会在我的代码下面找到:

    <?php
    public function updateStatus($message)
    {
        // Encoding message for the curl data parameter
        $messageData = rawurlencode($message);
    
        // Double encoding message for the message in signature base string
        $messageSignature = rawurlencode($messageData);
    
        // URL for posting a new tweet
        $statusURL = rawurlencode('https://api.twitter.com/'.$this->version.'/statuses/update.json');
    
        // Create oauth_nonce parameter
        $oauth_nonce = preg_replace('~[\W]~','',base64_encode(uniqid()));
    
        // Create timestamp
        $oauth_timestamp = time();
    
        // Create signature base string parameter
        $signature_base_string = "POST&".$statusURL."&oauth_consumer_key%3D".CB_TWITTER_API_KEY."%26oauth_nonce%3D".$oauth_nonce."%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D".$oauth_timestamp."%26oauth_token%3D".$this->sessionData['oauth_token']."%26oauth_version%3D1.0%26status%3D".$messageSignature."";
    
        // Create signature key 
        $signature_key = CB_TWITTER_SECRET_KEY.'&'.$this->sessionData['oauth_token_secret'];
    
        // Create new signature
        $newSignature = rawurlencode(base64_encode(hash_hmac('sha1', $signature_base_string, $signature_key, true)));
    
        // Create header
        $header="Authorization: 
                    OAuth 
                    oauth_consumer_key=\"".CB_TWITTER_API_KEY."\", 
                    oauth_nonce=\"".$oauth_nonce."\", 
                    oauth_signature=\"".$newSignature."\", 
                    oauth_signature_method=\"HMAC-SHA1\", 
                    oauth_timestamp=\"".$oauth_timestamp."\", 
                    oauth_token=\"".$this->sessionData['oauth_token']."\", 
                    oauth_version=\"1.0\"";
    
        // Replace line breaks and tabulations in header
        $header = preg_replace( "/\r|\n|\t/", "", $header);
    
        // Init cURL
        $ch = curl_init();
    
        // Put header
        curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));
    
        // Set request type to POST for POSTing a tweet
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    
        // Enable verbose for debugging only
        curl_setopt($ch, CURLOPT_VERBOSE, false);
    
        // Return the transfer in a string
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    
        // Set URL of cURL request
        curl_setopt($ch, CURLOPT_URL, rawurldecode($statusURL));
    
        // Do a POST request (HTML POST)
        curl_setopt($ch, CURLOPT_POST, 1);
    
        // Set data
        curl_setopt($ch, CURLOPT_POSTFIELDS, 'status='.$messageData);
    
        // Execute cURL and store result
        $output = curl_exec($ch);
    
        // Close cURL
        curl_close($ch);
    
        if ($output) {
            $output = json_decode($output);
        }
    
        if ($this->hasErrors($output, false))
        {
            return false;
        }
    
    
       return true;
    }
    ?>
    

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2015-09-16
      • 2013-03-14
      • 1970-01-01
      • 1970-01-01
      • 2011-12-14
      • 1970-01-01
      • 2010-12-01
      • 2012-04-08
      • 2011-04-09
      相关资源
      最近更新 更多