简体   繁体   English

通过oAuth授权,发布到Twitter

[英]Authorizing with oAuth, posting to Twitter

I've created a Twitter Application to auto-post to my Twitter account. 我已经创建了一个Twitter应用程序来自动发布到我的Twitter帐户。 So, I don't need to authorize new users. 所以,我不需要授权新用户。

I've already set access level to read/write, and received an access token. 我已经设置了读/写访问级别,并收到了访问令牌。 I've used the OAuth Tool in the application to generate a cURL command: 我在应用程序中使用了OAuth工具来生成cURL命令:

curl --request 'POST' ' https://api.twitter.com/1/statuses/update.json ' --data 'status=Maybe+he%27ll+finally+find+his+keys.+%23peterfalk' --header 'Authorization: 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 --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

Above the command, it says: 在命令之上,它说:

Important: This will only be valid for a few minutes. 重要提示:此功能仅在几分钟内有效。 Also remember the cURL command will actually execute the request. 还记得cURL命令实际上会执行请求。

I assume that this will work in a linux terminal. 我假设这将在Linux终端中工作。

I'd like to know how to translate this into a PHP cURL command. 我想知道如何将其转换为PHP cURL命令。 Here's what I've tried. 这是我尝试过的。 Note that value of $DST is the value of "DST" in https://dev.twitter.com/docs/auth/authorizing-request ; 请注意,$ DST的值是https://dev.twitter.com/docs/auth/authorizing-request中“DST”的值; it is also equal to the value of the string after --header 'Authorization: in the cURL command in the OAuth tool. 它也等于--header 'Authorization:后的字符串值--header 'Authorization:在OAuth工具的cURL命令中。

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

But the value of $resp is: $resp的价值是:

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

Is there something I'm doing wrong? 有什么我做错了吗? Note that the OAuth Tool said that the cURL command would actually work. 请注意,OAuth工具表示cURL命令实际上可以正常工作。 So I think it's just a matter of figuring out how to arrange the cURL in PHP. 所以我认为这只是要弄清楚如何在PHP中安排cURL。 I'm not very familiar with it. 我对它不是很熟悉。 Also note that I want to avoid using the OAuth libraries if I can. 另请注意,如果可以的话,我想避免使用OAuth库。 I feel like there should be a much more light-weight solution to this than to install a whole library. 我觉得应该有一个更轻量级的解决方案,而不是安装一个完整的库。

Hi and thank you for your help. 嗨,谢谢你的帮助。

I had the same problem, you'll find below my code: 我有同样的问题,你会在我的代码下面找到:

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

Hope it'll help. 希望它会有所帮助。

I had three problems: 我有三个问题:

(1) I did not include it in this question, but my signature wasn't created correctly. (1)我没有在这个问题中包含它,但我的签名没有正确创建。

What I was doing was base64_encode(hash_hmac('sha1', $base, $key)); 我正在做的是base64_encode(hash_hmac('sha1', $base, $key)); but I should have set the hash_hmac fourth parameter to true to return a raw binary instead of the hexidecimal (the hexidecimal is shown as the example in the Twitter docs, which was what was confusing me). 但我应该将hash_hmac第四个参数设置为true以返回原始二进制而不是十六进制(十六进制显示为Twitter文档中的示例,这让我感到困惑)。 The correct function is therefore: base64_encode(hash_hmac('sha1', $base, $key, true)); 因此,正确的函数是: base64_encode(hash_hmac('sha1', $base, $key, true)); .

(2) The cURL was not set up correctly. (2)cURL设置不正确。 I required CURLOPT_HTTPHEADER to set the Authorization, and CURL_VERBOSE set to true: 我需要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) As seen in the above code, I had to post the status as a string, and not an array. (3)如上面的代码所示,我不得不将状态发布为字符串,而不是数组。 I found the solution to this problem on this question: Why can't I authenticate with OAuth? 我在这个问题上找到了解决这个问题的方法: 为什么我不能使用OAuth进行身份验证? .

All of this is now working perfectly. 所有这一切现在都很完美。 Also, make sure that your access token in your Twitter application says that the access level is "Read and write". 此外,请确保您的Twitter应用程序中的访问令牌表明访问级别为“读写”。 If not, change the permissions in Settings, then go back to Details and recreate your access token. 如果没有,请更改“设置”中的权限,然后返回“详细信息”并重新创建访问令牌。

Full Script 完整的脚本

<?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'); 
*/

?>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM