another twitter oAuth cURL access token request that fails

后端 未结 4 2042
醉话见心
醉话见心 2020-11-29 07:14

The following function gives a validation error instead of the token:

failed to validate oAuth signature and token



        
相关标签:
4条回答
  • 2020-11-29 07:24

    not sure if your still looking into this, or if it will work for you, but i had a similar setup and had the same issue. I eventually found i was urlencoding one to many times. Try commenting out this section:

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

    Worked for me, so maybe it will help.

    0 讨论(0)
  • 2020-11-29 07:25

    Below is what Ive put together so far and it works :-)

        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 讨论(0)
  • 2020-11-29 07:36

    I faced same issue, what I was missing is passing header in to the curl request. As shown in this question, I was also sending the $header = array('Expect:'), which was the problem in my case. I started sending signature in header with other data as below and it solved the case for me.

    $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));
            }
        }
    
    0 讨论(0)
  • 2020-11-29 07:41

    I'll admit this isn't really an answer, but if you can, use the PECL OAuth package. Rasmus Lerdorf wrote a tutorial on how to use it and it got me around this same issue.

    0 讨论(0)
提交回复
热议问题