2014-09-10 148 views
0

我正在使用自定義代碼連接到Twitter並請求訪問令牌。出於某種原因,當嘗試在API上發佈「access_token」時,它會返回「無效或過期的令牌」。該代碼是如(除了少量的外部函數調用和屬性這應該是足夠的複製錯誤)如下:Twitter訪問令牌請求返回「無效或過期的令牌」

public function authenticate($get,$return = false) {             
    session_start();   

      if (!isset($get['oauth_verifier'])){ 
        // Step 1 - get a request token 
        $step1 = $this->processRequest('oauth/request_token',0,$this->pObj->getRedirectUrl().'?process=true');           
        parse_str($step1,$parts); 

        if ($parts['oauth_callback_confirmed'] !== 'true'){ die('Error with process'); } 

        $_SESSION['tw_secret'] = $parts['oauth_token_secret']; 

        // Step 2 
        $url = str_replace('1.1/','',$this->api_url); 
        header("Location: {$url}oauth/authenticate?oauth_token={$parts['oauth_token']}"); 
      } else { 
        // Step 3 
        $this->o_token = $get['oauth_token']; 
        $this->o_secret = $_SESSION['tw_secret'];      
        $content['oauth_verifier'] = $get['oauth_verifier']; 
        $step3 = $this->processRequest('oauth/access_token',1,null,$content,'array');      
      }   
    } 

    // https://dev.twitter.com/docs/auth/creating-signature 
    private function generateSignature($oauth,$fullurl,$http_method,$content){   

      // Take params from url 
      $main_url = explode('?',$fullurl); 

      // Split the content 
      $contents = explode('&',$content); 

      $urls = array_merge(explode('&',$main_url[1]),$contents); 

      foreach ($urls as $param){ 
        $bits = explode('=',$param); 
        if (strlen($bits[0])){ 
          $oauth[$bits[0]] = rawurlencode($bits[1]); 
        }  
      } 

      ksort($oauth); 

      $string = http_build_query($oauth); 

      $new_string = strtoupper($http_method).'&'.urlencode($main_url[0]).'&'.urlencode(urldecode($string)); 

      // The request_token request doesn't need a o_secret because it doesn't have one! 
      $sign_key = strstr($fullurl,'request_token') ? $this->c_secret.'&' : $this->c_secret.'&'.$this->o_secret;     

    return urlencode(base64_encode(hash_hmac('sha1',$new_string,$sign_key,true)));   
    } 

    public function processRequest($in_url,$test = false,$callback = null,$content = null, $content_type = 'json',$form_content_type = 'application/x-www-form-urlencoded'){     
    $method = 'GET'; 

      // Twitter still uses Oauth1 (which is a pain) 
      $oauth = array(
        'oauth_consumer_key'=>$this->c_key, 
        'oauth_nonce'=>$this->random(32), 
        'oauth_signature_method'=>'HMAC-SHA1', 
        'oauth_timestamp'=>time(), 
        'oauth_token'=>$this->o_token, 
        'oauth_version'=>'1.0' 
      ); 

      $url = $this->api_url.$in_url; 

      if (strlen($callback)){ 
        $oauth['oauth_callback'] = urlencode(urldecode($callback)); 
        unset($oauth['oauth_token']); 
        $method = 'POST'; 
        $url = str_replace('1.1/','',$url); 
      }     

      if (is_array($content) || strlen($content)){ $method = 'POST'; } 

      $oauth['oauth_signature'] = $this->generateSignature($oauth,$url,$method,'');         

      ksort($oauth); 

      foreach ($oauth as $k=>$v){ 
        $auths[] = $k.'="'.$v.'"'; 
      } 

      $stream = array('http' => 
            array(
              'method' => $method, 
              'ignore_errors'=>true, // http://php.net/manual/en/context.http.php - otherwise browser returns error not error content 
              'follow_location'=>false, 
              'max_redirects'=>0, 
              'header'=> array(
                    'Content-type: '.$form_content_type, 
                    'Authorization: OAuth '.implode(', ',$auths), 
                    'Connection: close' 
                  )            
            ) 
          );         

      if (is_array($content)){ 
        $content = $content_type == 'json' ? json_encode($content) : http_build_query($content); 
        /* foreach ($content as $k=>$v){ 
          $strs[] = "$k=".urlencode(urldecode($v));   
        } 

        // Just for now to keep things simple 
        $content = 'status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21';*/ 
      } 

      if (!is_null($content)){ 
        $stream['http']['content'] = $content; 
      }                

      // Tell streams to make a request 
      // Invalid key or 401 error tends to suggest an incorrect signing key/signature          
      $response = file_get_contents($url, false, stream_context_create($stream));    

      if ($test){ 
        print'<pre>';print_r($oauth);print'</pre>'; 
        print'<pre>';print_r($stream);print'</pre>'; 
        //echo $callback.'<br>'; 
        echo $url.'<br>'; 
        //print'<pre>';print_r($http_response_header);print'</pre>'; 
        print'<pre>[';print_r($response);print']</pre>'; 
      }         

      if (!is_object(json_decode($response))){ 
        // Content supplied is not json - just return it 
        return $response;       
      } else { 
        $response = json_decode($response); 
      }         

    return $this->pObj->convertObjectToArray($response);             
    }     

回答

0

的原因的問題是:

1)微博的版本不應包含API 2)該帖子缺少簽名中的Oauth_verifier

感謝twitteroauth提供了一些指示燈。

相關問題