我已经创建了一个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库。我觉得应该有一个更轻量级的解决方案,而不是安装整个库。
答案 0 :(得分: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;
}
?>
希望它会有所帮助。
答案 1 :(得分: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');
*/
?>