La API de Twitter devuelve el error 215, datos de autenticación incorrectos

110

Estoy tratando de llamar a la siguiente API de Twitter para obtener una lista de seguidores para 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?

Sumergir Dhingani
fuente
2
Muchos de nosotros estamos en el mismo barco. ¿Fuiste capaz de resolver esto? Me encantaría ver una solución para 1.1 ya que 1.0 está en desuso.
RCNeil
1
Lamentablemente, todavía no he podido encontrar una solución adecuada. Estoy trabajando en la versión 1 por ahora. Pero definitivamente lo publicaré aquí cuando lo haga. Y si lo obtiene antes de eso, por favor comparta ...
Dip Dhingani
1
¿Alguien ha notado en la herramienta oauth de Twitter que se genera una URL con "/1.1", pero el comando cURL dice "oauth_version = 1.0"? dev.twitter.com/apps/XXXXXX/oauth?nid=10364
systemblogger
1
@systemblogger Bueno, la versión de OAuth y la versión de la API de Twitter no son lo mismo. En cuanto a OAuth, hay 1.0 y 2.0 atm, y me alegro de que Twitter todavía use 1.0.
Vlasec
Aquí, primero, todos deben usar oauth2 / token api y luego usar seguidores / list api. De lo contrario, obtendrá este error. Porque la API de seguidores / lista requiere autenticación. En Swift, siga este enlace, stackoverflow.com/questions/12053159/…
iOS

Respuestas:

26

Un código muy conciso sin ningún otro archivo php que incluya oauth, etc. Tenga en cuenta que para obtener las siguientes claves debe registrarse en https://dev.twitter.com y crear la 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("&amp;","&",$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

Un trabajador brillante
fuente
Esto funciona debido a "CURLOPT_SSL_VERIFYPEER = false". Hemos rastreado que es un error de verificación del certificado SSL cURL, lo que hace que la biblioteca de Twitter siempre devuelva una respuesta vacía.
lubosdz
11

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 le proporciona Twitter. Utilice TwitterOAuth biblioteca para esto, es bastante fácil, vea los ejemplos que vienen con la biblioteca.
  • Con estos tokens, puede 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 le devolverá la lista de amigos del usuario.

Pavel
fuente
7

ENCONTRÓ UNA SOLUCIÓN: utilizando la biblioteca Abraham TwitterOAuth . Si está utilizando una implementación anterior, se deben agregar las siguientes líneas después de crear una 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 ahora están documentadas en el archivo Léame de la biblioteca de Abraham, pero la tercera no lo está. 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 devolver el nombre completo del usuario y el icono 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 tomó demasiado tiempo darme cuenta de esto. ¡¡Espero que esto ayude a alguien!!

Dante Cullari
fuente
5

La URL con /1.1/ que contiene es correcta, es la nueva versión 1.1 de la API de Twitter.

Pero necesita una aplicación y autorizar su aplicación (y el usuario) usando oAuth.

Lea más sobre esto en el sitio de documentación de Twitter Developers :)

spiele_r
fuente
141
Hacer referencia a un sitio de documentación no responde realmente a la pregunta.
moluv00
4
@ moluv00 OP dijo: "Parece que no puedo encontrar la documentación relacionada con este código de error".
strangerstudios
4
¿Por qué publicaste un enlace general? Ésta no es una respuesta.
Brice Favre
5

La respuesta de Gruik funcionó para mí en el siguiente hilo.

{Extracto | Zend_Service_Twitter - Prepare API v1.1 }

con ZF 1.12.3, la solución es pasar consumerKey y consumerSecret en la opción oauthOptions, no directamente en las opciones.

    $options = array(
        'username' => /*...*/,
        'accessToken' => /*...*/,
        'oauthOptions' => array(
            'consumerKey' => /*...*/,
            'consumerSecret' => /*...*/,
        )
    );
Jonathan Haar
fuente
5

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). Debe ser 1, no 1.1. Esto funcionará:

http://api.twitter.com/1/followers/ids.json?cursor=-1&screen_name=username

cristóbal
fuente
3
Sí, eso es correcto. Pero eso es porque la Documentación de Twitter me sugirió que lo hiciera. ( dev.twitter.com/docs/api/1/get/followers/ids ). Dijeron que la versión 1 está obsoleta y necesito pasar a la 1.1. La versión 1 funciona con seguridad para este servicio web. Pero estaba confundido por qué 1.1 no funciona para mí.
Dip Dhingani
7
La versión 1 quedará obsoleta en 6 meses a partir de marzo de 2013, así que optaría por la versión 1.1
K. Weber
Probando diferentes bibliotecas de OAuth me quedo con Twitter Async , simplemente cambiar esta línea protected $apiVersion = '1.1';en el archivo EpiTwitter.php funciona bien para la versión 1.1 de la API de Twitter
K. Weber
2
Twitter API 1 está en desuso
qasimzee
4
La API REST de Twitter v1 ya no está activa. Migra a la API v1.1. dev.twitter.com/docs/api/1.1/overview .
itsazzad
3

Después de dos días de investigación, finalmente descubrí que para acceder a tweets tan públicos solo necesitas cualquier credenciales de la aplicación, y no las de ese usuario en particular. Entonces, si está desarrollando para un cliente, no tiene que pedirle que haga nada.

Para utilizar la nueva API de Twitter 1.1, necesita dos cosas:

Primero, puede (en realidad tiene que) crear una aplicación con sus propias credenciales y luego obtener el token de acceso (OAUTH_TOKEN) y el token secreto de acceso (OAUTH_TOKEN_SECRET) de la sección " Su token de acceso ". Luego, los proporciona en el constructor del nuevo objeto TwitterOAuth. Ahora puede acceder a los tweets públicos de cualquier persona .

$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 también sugirió Pavel , pero no es tan obvio a partir de su respuesta.

Espero que esto salve a alguien más esos dos días :)

nobug
fuente
2

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)
));
Juan de Parras
fuente
2

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, mientras que twitter api 1.1 solo requiere que la versión de oauth sea 1.0.

PD: No usamos Zend_Service_Twitter ya que no permite enviar parámetros personalizados en la actualización de estado.

Maksim Kotlyar
fuente
0

Asegúrese de tener acceso de lectura Y escritura para la aplicación en Twitter

Víctor
fuente
0

Estoy usando HybridAuth y este error al conectarme a Twitter. Lo rastreé hasta (yo) enviando a Twitter un tipo de solicitud en mayúscula incorrecta (obtener / publicar 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 lo haría (porque HA proporciona internamente el valor correctamente en mayúsculas para el tipo de solicitud):

$call = '/search/tweets.json';
$call_args = array(
    'q'           => 'pancakes',
    'count'       => 5,
);
$response = $providers['Twitter']->get( $call, $call_args );
Skrivener
fuente
0

Me enfrentaba al mismo problema todo el tiempo, la única solución que imagino es escribir CONSUMER_KEYy CONSUMER_SECRETdirectamente a 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 se resolvió.

Salem
fuente
0

Aquí, primero, todos deben usar oauth2 / token api y luego usar seguidores / list api .
De lo contrario, obtendrá este error. Porque la API de seguidores / lista requiere autenticación.

En Swift (para aplicaciones móviles) también tuve el mismo problema.

Si desea conocer los parámetros de la API y sus, siga este enlace, ¿ Obtener la lista de amigos de Twitter rápidamente?

iOS
fuente
-1

Sé que esto es antiguo, pero ayer enfrenté el mismo problema al llamar a esta URL usando C # y la clase HttpClient con el token de autenticación del portador:

http://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=username

Resulta que la solución para mí fue 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
                }
            }
alejosoft
fuente
1
estoy consiguiendo{"errors":[{"message":"Bad Authentication data","code":215}]}
tq
@tq: Mira esta respuesta: stackoverflow.com/questions/12684765/…
alejosoft
-1

Prueba este explorador de API de Twitter , puedes iniciar sesión como desarrollador y consultar lo que quieras.

ethanjyx
fuente