php - example - La API de Twitter devuelve el error 215, Datos de autenticación incorrectos
twitter php (14)
Intento llamar al siguiente API de Twitter para obtener una lista de seguidores de un usuario.
http://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=username
Y recibo este mensaje de error en respuesta.
{
code = 215;
message = "Bad Authentication data";
}
Parece que no puedo encontrar la documentación relacionada con este código de error. ¿Alguien tiene alguna idea sobre este error?
Asegúrese de haber leído Y escribir el acceso para la aplicación en Twitter
Debe enviar customerKey y customerSecret a Zend_Service_Twitter
$twitter = new Zend_Service_Twitter(array(
''consumerKey'' => $this->consumer_key,
''consumerSecret'' => $this->consumer_secret,
''username'' => $user->screenName,
''accessToken'' => unserialize($user->token)
));
Después de dos días de investigación, finalmente descubrí que para acceder a tweets tan públicos solo necesitas las credenciales de la aplicación, y no las de usuario particulares. Entonces, si está desarrollando para un cliente, no tiene que pedirle que haga nada.
Para usar la nueva API de Twitter 1.1 necesita dos cosas:
- la biblioteca TwitterOAuth de Abraham que ya mencionó Dante Cullari
- una aplicación nueva o ya en funcionamiento creada a través del sitio de Twitter Developer
En primer lugar, puede (de hecho) crear una aplicación con sus propias credenciales y luego obtener el token de acceso (OAUTH_TOKEN) y el secreto de token de acceso (OAUTH_TOKEN_SECRET) en la sección " Su token de acceso ". Luego los suministra en el constructor para el nuevo objeto TwitterOAuth. Ahora puede acceder a cualquier tweet público.
$connection = new TwitterOAuth( CONSUMER_KEY, CONSUMER_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET );
$connection->host = "https://api.twitter.com/1.1/"; // change the default
$connection->ssl_verifypeer = TRUE;
$connection->content_type = ''application/x-www-form-urlencoded'';
$tweets = $connection->get(''http://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=''.$username.''&count=''.$count);
En realidad, creo que esto es lo que Pavel también ha sugerido, pero no es tan obvio por su respuesta.
Espero que esto le ahorre a alguien esos dos días :)
ENCONTRÉ UNA SOLUCIÓN - usando la biblioteca Abraham TwitterOAuth . Si está utilizando una implementación más antigua, las siguientes líneas se deben agregar después de la creación de la instancia del nuevo objeto TwitterOAuth:
$connection->host = "https://api.twitter.com/1.1/";
$connection->ssl_verifypeer = TRUE;
$connection->content_type = ''application/x-www-form-urlencoded'';
Las primeras 2 líneas están ahora documentadas en el archivo Léame de la biblioteca Abraham, pero el tercero no. También asegúrese de que su oauth_version aún sea 1.0.
Aquí está mi código para obtener todos los datos de usuario de ''users / show'' con un usuario recién autenticado y devolverle al usuario el nombre completo y el ícono de usuario con 1.1 - el siguiente código se implementa en el archivo de devolución de llamada de autenticación:
session_start();
require (''twitteroauth/twitteroauth.php'');
require (''twitteroauth/config.php'');
$consumer_key = ''****************'';
$consumer_secret = ''**********************************'';
$to = new TwitterOAuth($consumer_key, $consumer_secret);
$tok = $to->getRequestToken(''http://exampleredirect.com?twitoa=1'');
$token = $tok[''oauth_token''];
$secret = $tok[''oauth_token_secret''];
//save tokens to session
$_SESSION[''ttok''] = $token;
$_SESSION[''tsec''] = $secret;
$request_link = $to->getAuthorizeURL($token,TRUE);
header(''Location: '' . $request_link);
El siguiente código está en la redirección después de la autenticación y la solicitud de token
if($_REQUEST[''twitoa'']==1){
require (''twitteroauth/twitteroauth.php'');
require_once(''twitteroauth/config.php'');
//Twitter Creds
$consumer_key = ''*****************'';
$consumer_secret = ''************************************'';
$oauth_token = $_GET[''oauth_token'']; //ex Request vals->http://domain.com/twitter_callback.php?oauth_token=MQZFhVRAP6jjsJdTunRYPXoPFzsXXKK0mQS3SxhNXZI&oauth_verifier=A5tYHnAsbxf3DBinZ1dZEj0hPgVdQ6vvjBJYg5UdJI
$ttok = $_SESSION[''ttok''];
$tsec = $_SESSION[''tsec''];
$to = new TwitterOAuth($consumer_key, $consumer_secret, $ttok, $tsec);
$tok = $to->getAccessToken();
$btok = $tok[''oauth_token''];
$bsec = $tok[''oauth_token_secret''];
$twit_u_id = $tok[''user_id''];
$twit_screen_name = $tok[''screen_name''];
//Twitter 1.1 DEBUG
//print_r($tok);
//echo ''<br/><br/>'';
//print_r($to);
//echo ''<br/><br/>'';
//echo $btok . ''<br/><br/>'';
//echo $bsec . ''<br/><br/>'';
//echo $twit_u_id . ''<br/><br/>'';
//echo $twit_screen_name . ''<br/><br/>'';
$twit_screen_name=urlencode($twit_screen_name);
$connection = new TwitterOAuth($consumer_key, $consumer_secret, $btok, $bsec);
$connection->host = "https://api.twitter.com/1.1/";
$connection->ssl_verifypeer = TRUE;
$connection->content_type = ''application/x-www-form-urlencoded'';
$ucontent = $connection->get(''users/show'', array(''screen_name'' => $twit_screen_name));
//echo ''connection:<br/><br/>'';
//print_r($connection);
//echo ''<br/><br/>'';
//print_r($ucontent);
$t_user_name = $ucontent->name;
$t_user_icon = $ucontent->profile_image_url;
//echo $t_user_name.''<br/><br/>'';
//echo $t_user_icon.''<br/><br/>'';
}
Me llevó demasiado tiempo descubrir esto. ¡¡Espero que esto ayude a alguien!!
Esto podría ayudar a alguien que usa Zend_Oauth_Client a trabajar con la API de Twitter. Esta configuración de trabajo:
$accessToken = new Zend_Oauth_Token_Access();
$accessToken->setToken(''accessToken'');
$accessToken->setTokenSecret(''accessTokenSecret'');
$client = $accessToken->getHttpClient(array(
''requestScheme'' => Zend_Oauth::REQUEST_SCHEME_HEADER,
''version'' => ''1.0'', // it was 1.1 and I got 215 error.
''signatureMethod'' => ''HMAC-SHA1'',
''consumerKey'' => ''foo'',
''consumerSecret'' => ''bar'',
''requestTokenUrl'' => ''https://api.twitter.com/oauth/request_token'',
''authorizeUrl'' => ''https://api.twitter.com/oauth/authorize'',
''accessTokenUrl'' => ''https://api.twitter.com/oauth/access_token'',
''timeout'' => 30
));
Parece que Twitter api 1.0 permite que la versión de Oauth sea 1.1 y 1.0, donde Twitter api 1.1 requiere que solo la versión oauth sea 1.0.
PD: No usamos Zend_Service_Twitter ya que no permite enviar parámetros personalizados en la actualización de estado.
Estoy usando HybridAuth y me encontré con este error al conectarme a Twitter. Lo rastreé para (me) enviar a Twitter un tipo de solicitud incorrectamente envasada (get / post en lugar de GET / POST).
Esto causaría un 215:
$call = ''/search/tweets.json'';
$call_type = ''get'';
$call_args = array(
''q'' => ''pancakes'',
''count'' => 5,
);
$response = $provider_api->api( $call, $call_type, $call_args );
Esto no:
$call = ''/search/tweets.json'';
$call_type = ''GET'';
$call_args = array(
''q'' => ''pancakes'',
''count'' => 5,
);
$response = $provider_api->api( $call, $call_type, $call_args );
Nota al margen: en el caso de HybridAuth, lo siguiente tampoco (debido a que HA proporciona internamente el valor del contexto correcto para el tipo de solicitud):
$call = ''/search/tweets.json'';
$call_args = array(
''q'' => ''pancakes'',
''count'' => 5,
);
$response = $providers[''Twitter'']->get( $call, $call_args );
La única solución que he encontrado hasta ahora es:
- Crear aplicación en el panel de desarrolladores de Twitter
- Autorice al usuario con su aplicación (o su aplicación en la cuenta de usuario) y guarde "oauth_token" y "oauth_token_secret" que Twitter le brinda. Use la biblioteca de TwitterOAuth para esto, es bastante fácil, vea ejemplos que vienen con la biblioteca.
Al usar estos tokens puedes realizar solicitudes autenticadas en nombre del usuario. Puedes hacerlo con la misma biblioteca.
// Arguments 1 and 2 - your application static tokens, 2 and 3 - user tokens, received from Twitter during authentification $connection = new TwitterOAuth(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, $tokens[''oauth_token''], $tokens[''oauth_token_secret'']); $connection->host = ''https://api.twitter.com/1.1/''; // By default library uses API version 1. $friendsJson = $connection->get(''/friends/ids.json?cursor=-1&user_id=34342323'');
Esto te devolverá la lista de amigos del usuario.
La URL con /1.1/
es correcta, es la nueva API de Twitter versión 1.1.
Pero necesita una aplicación y autoriza su aplicación (y el usuario) usando oAuth.
Lea más sobre esto en el sitio de documentación de Desarrolladores de Twitter :)
La respuesta de Gruik funcionó para mí en el siguiente enlace.
{Extracto | Zend_Service_Twitter - Prepara la API v1.1 }
con ZF 1.12.3 la solución consiste en pasar consumerKey y consumerSecret en la opción oauthOptions, no directamente en las opciones.
$options = array(
''username'' => /*...*/,
''accessToken'' => /*...*/,
''oauthOptions'' => array(
''consumerKey'' => /*...*/,
''consumerSecret'' => /*...*/,
)
);
Me enfrentaba al mismo problema todo el tiempo. La única solución que figuraba era escribir CONSUMER_KEY
y CONSUMER_SECRET
directamente en la nueva definición de clase de TwitterOAuth.
$connection = new TwitterOAuth( "MY_CK" , "MY_CS" );
No use variables o estáticas en esto y vea si el problema es desaconsejable.
Prueba este twitter API explorer , puedes iniciar sesión como desarrollador y consultar lo que quieras.
Sé que esto es antiguo, pero ayer me enfrenté al mismo problema al llamar a esta URL usando C # y la clase HttpClient con el token de autenticación de portador:
http://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=username
Resultó que la solución para mí era usar HTTPS en lugar de HTTP. Entonces mi URL se vería así:
https : //api.twitter.com/1.1/followers/ids.json? cursor = -1 & screen_name = username
Así que aquí hay un fragmento de mi código:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://api.twitter.com/1.1/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Authorization", "Bearer **** YOUR BEARER TOKEN GOES HERE ****");
var response = client.GetAsync("statuses/user_timeline.json?count=10&screen_name=username").Result;
if (!response.IsSuccessStatusCode)
{
return result;
}
var items = response.Content.ReadAsAsync<IEnumerable<dynamic>>().Result;
foreach (dynamic item in items)
{
//Do the needful
}
}
Un código muy conciso sin ningún otro archivo php incluye oauth, etc. Tenga en cuenta que para obtener las siguientes claves debe registrarse con https://dev.twitter.com y crear una aplicación.
<?php
$token = ''YOUR_TOKEN'';
$token_secret = ''YOUR_TOKEN_SECRET'';
$consumer_key = ''CONSUMER_KEY'';
$consumer_secret = ''CONSUMER_SECRET'';
$host = ''api.twitter.com'';
$method = ''GET'';
$path = ''/1.1/statuses/user_timeline.json''; // api call path
$query = array( // query parameters
''screen_name'' => ''twitterapi'',
''count'' => ''5''
);
$oauth = array(
''oauth_consumer_key'' => $consumer_key,
''oauth_token'' => $token,
''oauth_nonce'' => (string)mt_rand(), // a stronger nonce is recommended
''oauth_timestamp'' => time(),
''oauth_signature_method'' => ''HMAC-SHA1'',
''oauth_version'' => ''1.0''
);
$oauth = array_map("rawurlencode", $oauth); // must be encoded before sorting
$query = array_map("rawurlencode", $query);
$arr = array_merge($oauth, $query); // combine the values THEN sort
asort($arr); // secondary sort (value)
ksort($arr); // primary sort (key)
// http_build_query automatically encodes, but our parameters
// are already encoded, and must be by this point, so we undo
// the encoding step
$querystring = urldecode(http_build_query($arr, '''', ''&''));
$url = "https://$host$path";
// mash everything together for the text to hash
$base_string = $method."&".rawurlencode($url)."&".rawurlencode($querystring);
// same with the key
$key = rawurlencode($consumer_secret)."&".rawurlencode($token_secret);
// generate the hash
$signature = rawurlencode(base64_encode(hash_hmac(''sha1'', $base_string, $key, true)));
// this time we''re using a normal GET query, and we''re only encoding the query params
// (without the oauth params)
$url .= "?".http_build_query($query);
$url=str_replace("&","&",$url); //Patch by @Frewuill
$oauth[''oauth_signature''] = $signature; // don''t want to abandon all that work!
ksort($oauth); // probably not necessary, but twitter''s demo does it
// also not necessary, but twitter''s demo does this too
function add_quotes($str) { return ''"''.$str.''"''; }
$oauth = array_map("add_quotes", $oauth);
// this is the full value of the Authorization line
$auth = "OAuth " . urldecode(http_build_query($oauth, '''', '', ''));
// if you''re doing post, you need to skip the GET building above
// and instead supply query parameters to CURLOPT_POSTFIELDS
$options = array( CURLOPT_HTTPHEADER => array("Authorization: $auth"),
//CURLOPT_POSTFIELDS => $postfields,
CURLOPT_HEADER => false,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false);
// do our business
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);
$twitter_data = json_decode($json);
foreach ($twitter_data as &$value) {
$tweetout .= preg_replace("/(http:////|(www/.))(([^/s<]{4,68})[^/s<]*)/", ''<a href="http://$2$3" target="_blank">$1$2$4</a>'', $value->text);
$tweetout = preg_replace("/@(/w+)/", "<a href=/"http://www.twitter.com///1/" target=/"_blank/">@//1</a>", $tweetout);
$tweetout = preg_replace("/#(/w+)/", "<a href=/"http://search.twitter.com/search?q=//1/" target=/"_blank/">#//1</a>", $tweetout);
}
echo $tweetout;
?>
Saludos
ACTUALIZACIÓN: Twitter API 1 ahora está en desuso. Consulte la respuesta anterior.
Twitter 1.1 no funciona con esa sintaxis (cuando escribí esta respuesta). Necesita ser 1, no 1.1. Esto funcionará:
http://api.twitter.com/1/followers/ids.json?cursor=-1&screen_name=username