我正在尽力使用PHP和OAuth(PECL扩展程序)将图像上传到Twitpic,并且我不断收到以下错误:
无法对您进行身份验证(标题被Twitter拒绝)
到目前为止,这是我的代码:
$arguments[] = "oauth_consumer_key=" . $this->consumer_key;
$arguments[] = "oauth_nonce=" . md5(time());
$arguments[] = "oauth_signature_method=HMAC-SHA1";
$arguments[] = "oauth_timestamp=" . time();
$arguments[] = "oauth_token=" . $this->oauth_token;
$arguments[] = "oauth_version=1.0";
$sbs = oauth_get_sbs("POST", "http://api.twitpic.com/2/upload.xml", $arguments);
$signature = urlencode(base64_encode(hash_hmac("sha1", $sbs, $this->consumer_secret . "&", true)));
$arguments[] = "oauth_signature=" . $signature;
sort($arguments);
$headers[] = "X-Auth-Service-Provider: http://api.twitter.com/1/account/verify_credentials.json";
$headers[] = "X-Verify-Credentials-Authorization: OAuth\n" . implode(",\n", $arguments);
$postfields["key"] = $this->api_key;
$postfields["media"] = "@$image";
$postfields["message"] = $message;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "http://api.twitpic.com/2/upload.xml");
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_VERBOSE, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
echo curl_exec($curl);
有人能告诉我我做错了什么吗?
答案 0 :(得分:3)
我使用oauth echo遇到了很多麻烦,但过了几天这里是我的工作代码:)希望它能帮到你:
<?php
$timestamp = time();
$nonce = md5(uniqid(rand(), true));
$consumer_key = 'o6HXSybcBTrF9sylWzr04wzLjudbdZBQDpxGRdnBM';
$access_token = '147679787-tPB5UjfzQ1OPmn8JHzHmDWRYmI2yzN1Q9eMocGA';
$access_secret = 'hiding';
$consumer_secret = 'hiding';
$twitpic_url = 'http://api.twitpic.com/2/upload.json';
$args['key'] = 'hiding'; //This is your twitpic api key
$args['message'] = "testing twitpic from api";
$args['media'] = "@/tmp/linux.png" ; //Don't forget the @
//Here we build the oauth headers args which will be used for the signature base string
$oauth_args['oauth_consumer_key'] = $consumer_key;
$oauth_args['oauth_nonce'] = $nonce;
$oauth_args['oauth_signature_method'] = "HMAC-SHA1";
$oauth_args['oauth_timestamp'] = $timestamp;
$oauth_args['oauth_token'] = $access_token;
$oauth_args['oauth_version'] = "1.0";
$sbs_args = $oauth_args;
//We sort it...
ksort($sbs_args);
$url = 'https://api.twitter.com/1/account/verify_credentials.json';
$sbs = oauth_get_sbs(OAUTH_HTTP_METHOD_GET, $url, $sbs_args);
//This above function is from pecl oauth package
//It can be easily replaced by a homemade function for no dependancy code
//Here is the signature_base_string which is generated :
/*
GET&http%3A%2F%2Fapi.twitter.com%2F1%2Faccount%2Fverify_credentials.json&oauth_consumer_key%3DtL0auuqfuu8vyHt5Md9bg%26oauth_nonce%3Dacb327b80ae4bf35e895774f89a6afe2%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1285880687%26oauth_token%3D147679787-tPB5UjfzQ1OPmn8JHzHmDWRYmI2yzN1Q9eMocGA%26oauth_version%3D1.0
/*
* You should use a function to concatenate your keys ($access_secret is not mandatory. The function would encode the keys before concatenating (as far as i've seen in others sources...
*/
$key = $consumer_secret.'&'.$access_secret;
$signature = urlencode(base64_encode(hash_hmac('sha1', $sbs, $key, true)));
$headers =
<<<EOF
OAuth realm="http://api.twitter.com/", oauth_consumer_key="$consumer_key", oauth_signature_method="HMAC-SHA1", oauth_token="$access_token", oauth_timestamp="$timestamp", oauth_nonce="$nonce", oauth_version="1.0", oauth_signature="$signature"
EOF;
//Everything must be on a single line...
/*
* In fact, as you can see, the signature is generated against twitter verify_credentials.json
* and not against twitpic upload url...The base signature string does NOT take the twitpic
* parameters !! This is where i had lots of troubles...
* To be clear, we have to generate a header with oauth parameters only, we have to build
* a base signature string with those parameters sorted and the verifiy_credentials.json url
* in the same way as if we would authenticate directly against twitter (no twitpic magic here)
*/
$curl = curl_init();
//We are going to call twitpic api, not twitter :
curl_setopt($curl, CURLOPT_URL, $twitpic_url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FAILONERROR, false);
// Set our OAuth Echo headers
/*
* This is the oauth magic. We pass to twitpic the url where he has to authorize user
* We pass the header to pass to this url.
* We constructed a beautifull header ready for verify_credentials.json
* Twitpic will send this header to twitter by calling verify_credentials.json
* And then continue process if twitter answer correctly !
*/
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'X-Verify-Credentials-Authorization: ' . $headers,
'X-Auth-Service-Provider: ' . $url
));
//We post your $args array with you api key, message, and media...
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $args);
$response = curl_exec($curl);
if (!$response) {
$response = curl_error($curl);
}
curl_close($curl);
//Twitpic json respone
var_dump($response);
?>
事情是,twitpic api文档远非明确。 当你知道你必须打电话给https://api.twitter.com/1/account/verify_credentials.json而不是http://api.twitpic.com/2/upload.json时,它开始是更容易......当你知道在你的签名基本字符串中你只需要oauth_parameters它就更容易了......
希望它能帮到你!