OAuth – ошибка в Twitter (не удалось аутентифицировать)

Я написал класс (так что я мог бы узнать, как работает OAuth). Он работает нормально; Я могу получить токен доступа с классом. Но когда я пытаюсь опубликовать обновление, он говорит, что я не аутентифицирован! Что я здесь делаю неправильно?

// By Kevin Jacobs class OAuth { private $url = null; private $debug = false; private $method = 'POST'; private $oauthData = array(); private $data = array(); private $token = array('key' => '', 'secret' => ''); private $consumer = array('key' => '', 'secret' => ''); /** * Encode a string in such a way you can use it for OAuth. * @param string $oauthData Data to encode * @return string $encData Encoded data */ public static function encode($oauthData) { if (is_string($oauthData)) { return str_ireplace( array('+', '%7E'), array(' ', '~'), rawurlencode($oauthData) ); } else { return ''; } } /** * Generates a relative unique random string of a certain length. * @param int $length Length of the string * @return string $strRand A random string */ public static function generateString($length = 40) { // Only strong cryptographic strings are allowed while (!isset($bStrong) || $bStrong === false) { $bytes = openssl_random_pseudo_bytes(floor($length / 2), $bStrong); } $strRand = bin2hex($bytes); return sha1($strRand); } /** * Generate a token pair (key and secret). * @return array $tokenPair */ public static function generateTokenPair() { $tokenPair = array(); $tokenPair['key'] = self::generateString(); $tokenPair['secret'] = self::generateString(); return $tokenPair; } /** * Set the callback URL. * @param string $callbackURL */ public function setCallback($callback = null) { if ($callback === null) { $callback = 'http'; if ($_SERVER['SERVER_PORT'] == 443) $callback .= 's'; $callback .= '://' . $_SERVER['SERVER_NAME']; if ($_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443) { $callback .= ':' . $_SERVER['SERVER_PORT']; } $callback .= $_SERVER['REQUEST_URI']; } $this->oauthData['oauth_callback'] = $callback; } /** * Get the callback URL. * @return string $callbackURL */ public function getCallback() { return $this->oauthData['oauth_callback']; } /** * Generate the nonce. * @return string $nonce */ public function setNonce() { $this->oauthData['oauth_nonce'] = md5(self::generateString(20) . mktime()); return $this->oauthData['oauth_nonce']; } /** * Set the timestamp. * @return int $timestamp */ public function setTimestamp() { $this->oauthData['oauth_timestamp'] = mktime(); return $this->oauthData['oauth_timestamp']; } /** * Set the OAuth version. * @param string Version */ public function setVersion($version = '1.0') { $this->oauthData['oauth_version'] = $version; } /** * Set the HTTP method. * @param string Method */ public function setMethod($method = 'POST') { $this->method = trim(strtoupper($method)); } /** * Get the HTTP method. * @return string Method */ public function getMethod() { return $this->method; } /** * Get the URL to call. * @return string URL */ public function getURL() { return $this->url; } /** * Set the URL to call. * @param string URL */ public function setURL($URL) { $this->url = $URL; } /** * Get the token key and secret * @return array $token Containing token key and secret */ public function getToken() { return $this->token; } /** * Set the token * @param string $tokenKey Token key * @param string $tokenSecret Token secret */ public function setToken($tokenKey, $tokenSecret = null) { $this->token['key'] = $tokenKey; $this->token['secret'] = $tokenSecret; $this->oauthData['oauth_token'] = $tokenKey; $this->oauthData['oauth_token_secret'] = $tokenSecret; } /** * Get the consumer * @return array $consumer Containing consumer key and secret */ public function getConsumer() { return $this->consumer; } /** * Set the consumer * @param string $consumerKey Consumer key * @param string $consumerSecret Consumer secret */ public function setConsumer($consumerKey, $consumerSecret) { $this->oauthData['oauth_consumer_key'] = $consumerKey; $this->consumer['key'] = $consumerKey; $this->consumer['secret'] = $consumerSecret; } /** * Generate the signature. * @return array Signature properties */ public function setSignature() { // Set the signature method $this->oauthData['oauth_signature_method'] = 'HMAC-SHA1'; // First, sort the OAuth data $oauthData = $this->oauthData; ksort($oauthData); // Now combine them in a string $query = http_build_query($oauthData); // Make it URL proof $query = rawurlencode($query); // Fetch the method and URL $method = $this->getMethod(); $url = $this->getURL(); // Make the URL URL proof $url = rawurlencode($url); // Now bind everything together $baseString = $method . '&' . $url . '&' . $query; // Retrieve the key $consumer = $this->getConsumer(); $token = $this->getToken(); $key = self::encode($consumer['secret']) . '&' . self::encode($token['secret']); // Encrypt the base string $signature = hash_hmac('SHA1', $baseString, $key, true); // And make it URL proof using base64_encode $signature = base64_encode($signature); $this->oauthData['oauth_signature'] = $signature; } public function setVerifier($verifier) { $this->oauthData['oauth_verifier'] = $verifier; } public function debugOn() { $this->debug = true; } public function debugOff() { $this->debug = false; } public function setData($data) { $this->data = $data; } public function call($url) { $method = $this->getMethod(); $this->setURL($url); $this->setNonce(); $this->setTimestamp(); $this->setSignature(); $oauthData = $this->oauthData; $data = $this->data; $data = array_merge($data, $oauthData); if ($method == 'GET') { $url = explode('#', $url); $url = reset($url); if (strpos($url, '?') !== false) { $binder = '&'; } else { $binder = '?'; } $url .= $binder . http_build_query($oauthData); } $ch = curl_init(); if (!empty($headers)) { curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); if ($method == 'POST') { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $oauthData); } curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_FAILONERROR, false); curl_setopt($ch, CURLOPT_MAXREDIRS, 10); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_ENCODING, ''); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); $result = curl_exec($ch); curl_close($ch); return $result; } } $x = new OAuth(); $x->debugOn(); $x->setVersion('1.0'); $x->setConsumer('consumerToken', 'consumerSecret'); $x->setToken('accessToken', 'accessSecret'); $x->setMethod('POST'); $x->setData(array('status' => 'Hello World!')); echo $x->call('http://api.twitter.com/1/statuses/update.json', true); 

Выполняется следующий код (получение токена доступа):

 $x = new OAuth(); $x->debugOn(); $x->setVersion('1.0'); $x->setConsumer('consumerToken', 'consumerSecret'); $x->setToken('accessToken', 'accessSecret'); $x->setMethod('POST'); if (isset($_GET['oauth_verifier']) && isset($_GET['oauth_token'])) { // Request token -> Access token $verifier = $_GET['oauth_verifier']; $token = $_GET['oauth_token']; $x->setVerifier($verifier); $x->setToken($token); $x->setMethod('GET'); $result = $x->call('https://api.twitter.com/oauth/access_token', true); parse_str($result); echo 'Access token: ' . $oauth_token . '<br />'; echo 'Access token secret: ' . $oauth_token_secret; } else { // Request token $x->setCallback(); $x->setMethod('GET'); $result = $x->call('https://api.twitter.com/oauth/request_token'); parse_str($result); header('Location: http://api.twitter.com/oauth/authorize?oauth_token=' . $oauth_token); } 

Я как бы догадываюсь здесь, но поскольку вы только говорите о «получении токена доступа с классом», я подозреваю, что вы не выполняете весь поток авторизации в OAuth Twitter. Первоначальный токен, который вы возвращаете, – это только ваша отправная точка для получения реального токена, который вы сможете использовать для публикации обновлений; вы должны прыгать через кучу обручей .

Если я ошибаюсь, и вы действительно прошли через эти обручи, неважно. 🙂