2010-09-28 30 views
1

Je suis en train de mon mieux pour télécharger des images à Twitpic en utilisant PHP et OAuth (extension PECL) et je continue à obtenir l'erreur suivante:l'authentification et le rejet d'en-tête avec Twitpic et OAuth

Could not authenticate you (header rejected by twitter)

Ceci est mon code pour loin:

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

Quelqu'un peut-il me dire ce que je fais mal?

Répondre

3

je suis tombé sur un tas de problèmes en utilisant l'écho oauth, mais après quelques jours voici mon code de travail :) Je espère que ça va vous aider:

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

?> 

Les choses est que la documentation Twitpic api est loin d'être être explicite. Lorsque vous savez que vous devez forger un appel pour https: //api.twitter.com/1/account/verify_credentials.json et non pour http: //api.twitpic.com/2/upload.json, il commence à soyez plus facile ... Quand vous savez que dans votre chaîne de base de signature vous n'avez besoin que de paramètres oauth, c'est encore plus facile ...

J'espère que ça va vous aider!