Следующая функция дает ошибку проверки вместо токена:
не удалось проверить подпись и токен oAuth
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>"; }
Ниже приведено то, что я собрал до сих пор, и он работает 🙂
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 ''; } } }
не уверен, если вы все еще смотрите на это, или если он будет работать для вас, но у меня была аналогичная настройка и была та же проблема. В конце концов я обнаружил, что уранокодировал один раз много раз. Попробуйте прокомментировать этот раздел:
$keys = $this->_urlencode_rfc3986(array_keys($params)); $values = $this->_urlencode_rfc3986(array_values($params)); $params = array_combine($keys, $values);
Работал для меня, так что, возможно, это поможет.
Я признаю, что на самом деле это не ответ, но если вы можете, используйте пакет PECL OAuth. Расмус Лердорф написал учебник о том, как его использовать, и он заставил меня обойти эту же проблему.
Я столкнулся с такой же проблемой, что мне не хватало, это передать заголовок в запрос curl. Как показано в этом вопросе, я также отправлял $ header = array ('Expect:'), что было проблемой в моем случае. Я начал отправлять подпись в заголовке с другими данными, как показано ниже, и он решил это для меня.
$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)); } }