2010-07-21 11 views
5

Die folgende Funktion schlägt fehl, gibt einen Validierungsfehler anstelle des Tokens:andere twitter oAuth cURL Zugriffstoken Anfrage, die

fehlgeschlagen oAuth Signatur und Token

function request_token() 
{ 
    // Set url 
    $url = $this->site.$this->request_token_path; // http://api.twitter.com/oauth/request_token 

    // Params to pass to twitter and create signature 
    $params['oauth_consumer_key'] = $this->consumerKey; 
    $params['oauth_token'] = ''; 
    $params['oauth_nonce'] = SHA1(time()); 
    $params['oauth_timestamp'] = time(); 
    $params['oauth_signature_method'] = $this->signatureMethod; // HMAC-SHA1; 
    $params['oauth_version'] = $this->version; // 1.0 
    ksort($params); 

    //print "<pre>"; print_r($params); print "</pre>"; 

    // Create Signature 
    $concatenatedParams = ''; 
    foreach($params as $k => $v){ 
     $concatenatedParams .= "{$k}={$v}&"; 
    } 
    $concatenatedParams = substr($concatenatedParams,0,-1); 

    $signatureBaseString = "POST&".urlencode($url)."&".urlencode($concatenatedParams); 
    $params['oauth_signature'] = base64_encode(hash_hmac('SHA1', $signatureBaseString, $this->secret."&", TRUE)); 

    // Do cURL 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLINFO_HEADER_OUT, 0); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); 
    curl_setopt($ch, CURLOPT_HEADER, 1); 
    curl_setopt($ch, CURLOPT_POST, 1); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1); 
    $exec = curl_exec ($ch); 
    $info = curl_getinfo($ch); 
    curl_close ($ch); 

    print $exec; 

    //print "<pre>"; print_r($info); print "</pre>"; 
} 
+0

Nur ein Kopf hoch. Twitter hat Probleme mit oAuth. Dies ist möglicherweise nicht dein Problem. http://dev.twitter.com/status –

+0

danke - ich glaube nicht, dass das ... –

Antwort

24

Unten ist das, was Ive zusammen so weit gesetzt und es funktioniert :-)

class Twitauth 
    { 
     var $key = ''; 
     var $secret = ''; 

     var $request_token = "https://twitter.com/oauth/request_token"; 

    function Twitauth($config) 
    { 
     $this->key = $config['key']; // consumer key from twitter 
     $this->secret = $config['secret']; // secret from twitter 
    } 

    function getRequestToken() 
    { 
     // Default params 
     $params = array(
      "oauth_version" => "1.0", 
      "oauth_nonce" => time(), 
      "oauth_timestamp" => time(), 
      "oauth_consumer_key" => $this->key, 
      "oauth_signature_method" => "HMAC-SHA1" 
     ); 

     // BUILD SIGNATURE 
      // encode params keys, values, join and then sort. 
      $keys = $this->_urlencode_rfc3986(array_keys($params)); 
      $values = $this->_urlencode_rfc3986(array_values($params)); 
      $params = array_combine($keys, $values); 
      uksort($params, 'strcmp'); 

      // convert params to string 
      foreach ($params as $k => $v) {$pairs[] = $this->_urlencode_rfc3986($k).'='.$this->_urlencode_rfc3986($v);} 
      $concatenatedParams = implode('&', $pairs); 

      // form base string (first key) 
      $baseString= "GET&".$this->_urlencode_rfc3986($this->request_token)."&".$this->_urlencode_rfc3986($concatenatedParams); 
      // form secret (second key) 
      $secret = $this->_urlencode_rfc3986($this->secret)."&"; 
      // make signature and append to params 
      $params['oauth_signature'] = $this->_urlencode_rfc3986(base64_encode(hash_hmac('sha1', $baseString, $secret, TRUE))); 

     // BUILD URL 
      // Resort 
      uksort($params, 'strcmp'); 
      // convert params to string 
      foreach ($params as $k => $v) {$urlPairs[] = $k."=".$v;} 
      $concatenatedUrlParams = implode('&', $urlPairs); 
      // form url 
      $url = $this->request_token."?".$concatenatedUrlParams; 

     // Send to cURL 
     print $this->_http($url);   
    } 

    function _http($url, $post_data = null) 
    {  
     $ch = curl_init(); 

     curl_setopt($ch, CURLOPT_URL, $url); 
     curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); 
     curl_setopt($ch, CURLOPT_TIMEOUT, 30); 
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 

     if(isset($post_data)) 
     { 
      curl_setopt($ch, CURLOPT_POST, 1); 
      curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); 
     } 

     $response = curl_exec($ch); 
     $this->http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE); 
     $this->last_api_call = $url; 
     curl_close($ch); 

     return $response; 
    } 

    function _urlencode_rfc3986($input) 
    { 
     if (is_array($input)) { 
      return array_map(array('Twitauth', '_urlencode_rfc3986'), $input); 
     } 
     else if (is_scalar($input)) { 
      return str_replace('+',' ',str_replace('%7E', '~', rawurlencode($input))); 
     } 
     else{ 
      return ''; 
     } 
    } 
} 
+0

schön! Es funktioniert, am Ende der Methode "getRequestToken" gibt es einen "Druck" anstelle einer "Rückgabe". – Pons

+0

Cool, froh, dass es geholfen hat :-) –

+0

Ich versuche, dieses Ding in C# arbeiten (weiß nicht PHP), damit ich ein wenig verwirrt bin.Ist var $ geheime, geheime Verbraucherschlüssel von Twitter? –

5

nicht sicher, ob Ihr noch in diese suchen, oder wenn es für Sie arbeiten, aber ich hatte ein ähnliches Setup und hatte das gleiche Problem. Irgendwann fand ich heraus, dass ich ein oder mehrere Male urlencodierte. Versuchen Sie diesen Abschnitt zu kommentieren out:

$keys = $this->_urlencode_rfc3986(array_keys($params)); 
     $values = $this->_urlencode_rfc3986(array_values($params)); 
     $params = array_combine($keys, $values); 

für mich gearbeitet, so wird es vielleicht helfen.

+2

http://stackoverflow.com/users/195192/good-bye sollte seinen Beitrag ändern, danke für diesen Einblick auf seine Antwort! – Erik

0

Ich sah das gleiche Problem, was ich vermisste ist Header in die Curl Anfrage übergeben. Wie in dieser Frage gezeigt, habe ich auch das Array $ header = ('Expect:') gesendet, was in meinem Fall das Problem war. Ich fing an, Unterschrift in der Überschrift mit anderen Daten wie unten zu senden und es löste den Fall für mich.

$header = calculateHeader($parameters, 'https://api.twitter.com/oauth/request_token'); 

function calculateHeader(array $parameters, $url) 
    { 
     // redefine 
     $url = (string) $url; 

     // divide into parts 
     $parts = parse_url($url); 

     // init var 
     $chunks = array(); 

     // process queries 
     foreach($parameters as $key => $value) $chunks[] = str_replace('%25', '%', urlencode_rfc3986($key) . '="' . urlencode_rfc3986($value) . '"'); 

     // build return 
     $return = 'Authorization: OAuth realm="' . $parts['scheme'] . '://' . $parts['host'] . $parts['path'] . '", '; 
     $return .= implode(',', $chunks); 

     // prepend name and OAuth part 
     return $return; 
    } 

function urlencode_rfc3986($value) 
    { 
     if(is_array($value)) return array_map('urlencode_rfc3986', $value); 
     else 
     { 
      $search = array('+', ' ', '%7E', '%'); 
      $replace = array('%20', '%20', '~', '%25'); 

      return str_replace($search, $replace, urlencode($value)); 
     } 
    }