Usando Twitter como sistema de autenticación en tu sitio
En estos días es una moda que uno delegue la autenticación de usuarios a un sistema ajeno, como Facebook Connect, Twitter OAuth u OpenID. Por una parte te ahorras el tener que almacenar contraseñas, validar correos y demás dramas del registro de usuarios; por otra dependes de las reglas de un tercero, o que este esté fuera de linea... etc.
Hoy veremos como hacer que los usuarios inicien sesión en nuestro sitio usando el API de Twitter. Esto tiene sentido si nuestro sitio planea hacer uso responsable del API y los accesos a la cuenta del usuario. Acá solo hablaré de como hacerlo a nivel general con PHP, sin usar un framework en particular, si ustedes usan otro lenguaje o herramientas, los principios son los mismos.
Primero veamos como funciona el proceso y luego lo pondremos en marcha. Para empezar necesitamos:
- Tener una aplicación registrada en Twitter y saber los valores del
consumer key
yconsumer secret
. Es muy importante que estos valores no sean públicos, manténlos en secreto - Necesitamos una librería que se encargue de comunicarse al API usando OAuth, acá usaremos la de Abraham Williams
A grandes rasgos el proceso de autenticación vía Twitter es de la siguiente forma:
Nota: Los tokens
no son otra cosa más que llaves usadas para identificar al usuario mientras se completa el proceso. Ahora veamos el proceso a detalle y con código.
Construir el URL de autenticación
Primero necesitamos una instancia de la clase TwitterOauth y con esta pediremos un identificador único al API, el mismo que nos servirá para tener una URL única hacia la que enviaremos al usuario. Digamos que esto solo se ejecuta cuando el usuario visita /login
en nuestra app
// En alguna parte de app.php // if ( $request == '/login' ) { $url = oauth_authlink( $config['oauth_callback'] ); header('Location: ' . $url, true, 302); die; }
// auth.php // function oauth_authlink( $callback = '' ) { include_once( 'twitterOAuth.php' ); oauth = new TwitterOAuth( CONSUMER_KEY, CONSUMER_SECRET ); oauth_clearcookies(); /* Solicitar el token a twitter */ $tok = $oauth->getRequestToken( $callback ); /* Dejar los tokens guardados al usuario para pasos después, son temporales */ setcookie('oauth_request_token', $tok['oauth_token'], 0 ); setcookie('oauth_request_token_secret', $tok['oauth_token_secret'] , 0 ); /* Construir el url de autenticación */ return $oauth->getAuthorizeURL($tok['oauth_token'],true); }
- Solo cuando el usuario visita
/login
se genera la URL única de autenticación, esto nos evita estár llamando al API a cada instante. Notar que la ejecución termina al enviar la redirección conheader()
- El valor de
$callback
enoauth_authlink()
es por si usamos una URL a la cual Twitter deba enviar al usuario de regreso a nuestra aplicación (ver paso 3), diferente a la que fue indicada en el registro de dicha aplicación. - Los primeros tokens de la petición se guardan en cookies, esto nos sirve para reconocer al usuario más tarde en el proceso; son temporales y luego los borramos con
oauth_clearcookies()
Recepción de la autorización
Twitter muestra al usuario la página donde le informa que nuestra aplicación solicita acceso a su cuenta; si en caso aún no ha iniciado sesión con Twitter, antes le pide registrarse para luego autorizar la aplicación.
Solo nos interesa cuando el usuario nos autoriza el acceso y Twitter lo manda de regreso a nuestra aplicación. Si quedamos perdidos entre las pestañas del navegador o no confía en nosotros, es otra historia que no sabremos. Si previamente el usuario ya autorizó nuestra aplicación, Twitter no le pedirá permiso de nuevo y automáticamente redirecciona hacia nosotros.
Twitter enviará a usuario a la URL que indicamos durante el registro de la aplicación en Callback URL
, o bien si enviamos una con $callback
(ver arriba). Asumamos que fue hacia /auth
donde Twitter envía a los usuarios:
// En alguna parte de app.php // if ( strpos( $request , '/auth')===0 ) { authenticate_user(); }
// auth.php // function oauth_authenticate() { $token = isset( $_GET['oauth_token'] ) ? $_GET['oauth_token'] : ''; $oauth_verifier = isset( $_GET['oauth_verifier'] ) ? $_GET['oauth_verifier'] : null; if ( $token == '' || !isset($_COOKIE['oauth_request_token']) || !isset($_COOKIE['oauth_request_token_secret']) || $_COOKIE['oauth_request_token']=='' || $_COOKIE['oauth_request_token_secret']=='' || $token != $_COOKIE['oauth_request_token'] ) { return false; } // Usamos los tokens temporales include_once( 'twitterOAuth.php' ); $to = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $_COOKIE['oauth_request_token'], $_COOKIE['oauth_request_token_secret']); /* Ahora solicitamos los tokens de acceso, que serán permanentes */ $tok = $to->getAccessToken( $oauth_verifier ); if ( $to->lastStatusCode() != 200 ) return false; $token = (string) $tok['oauth_token']; $token_secret = (string) $tok['oauth_token_secret']; $userid = (int) $tok['user_id']; if ($userid == 0 || empty($token) || empty($token_secret) ) return false; $info = array(); $info['userid'] = $userid; $info['token'] = $token; $info['token_secret'] = $token_secret; return $info; } function authenticate_user() { $info = oauth_authenticate(); if ( $info == false || !is_array($info) ) { die( 'Autenticación no completada, datos incorrectos' ); // ustedes deben usar algo más elegante que die() } global $db; $user = $db->get_user( $info['userid'] ); if ( empty($user) ) // primera vez por acá { $user = $db->add_user_from_twitter($info['userid'], $info['token'], $info['token_secret']) } else { // solo actualizar los tokens de acceso $db->update_user_tokens($info['userid'], $info['token'], $info['token_secret']); } oauth_clearcookies(); auth_create_cookie( $info['userid'] ); global $config; header('Location: ' . $config['site_url'], true, 301); die; }
¡Más código! Pero vamos por partes explicándolo:
oauth_authenticate()
es la función encargada de validar al usuario respecto al API.- Twitter nos envía varios parametros,
oauth_token
nos sirve para saber que usuario estamos procesando, cuyo valor es el mismo que solicitamos en el paso 1. Como nosotros guardamos estos tokens temporales como cookies, también los recibimos con la petición, de allí que comparemos si$token != $_COOKIE['oauth_request_token']
. Por otra parte Twitter también nos envíaoauth_verifier
si estamos usando uncallback URL
diferente, el cual debemos usarlo al solicitar los tokens de acceso. - Bien podríamos guardar los tokens temporales en la base de datos, ya que
oauth_token
nos sirve para saber cual estamos trabajando. Por ahora cookies resulta más fácil de trabajar. authenticate_user()
es la función que va comunicarse con el resto de su aplicación/framework, se supone que ustedes ya tienen todas las llamadas a las funciones $db->* (con el correspondiente nombre de función que ustedes usen).$db->add_user_from_twitter()
agrega un nuevo usuario a su aplicación con los datos regresados por twitter, seguramente quieran llamar al API para tener el nombre real y el username en base al ID devuelto por twitter (ver$info['userid']
).$db->update_user_tokens()
solo actualiza los tokes de acceso, en caso de que sean diferentes desde la ultima autorización. De nuevo estas son funciones que ustedes las deben adaptar a su aplicación.auth_create_cookie()
crea los cookies de autenticación para su aplicación, que son diferentes a las que usamos temporalmente para twitter. No hay necesidad de estar autenticando de ahora en adelante con el API. Esto es similar a cuando ya sabemos que el usuario y contraseña son correctos, creamos las cookies que usaremos para validar al usuario (sin que vuelva a darnos su usuario y contraseña).- Verificado el usuario y creadas las cookies, regresamos al usuario a la portada de nuestro sitio (o donde corresponda en su sitio).
De acá en adelante ya solo tenemos que usar los tokens de acceso, para llamar al API a nombre del usuario. Se asume que estos son permanentes, hasta que el usuario revoque la autorización a su cuenta.
¿Qué pasa si solo queremos actuar a nombre del usuario, pero no usar Twitter como sistema de autenticación en nuestra aplicación/sitio? Solo tenemos que cambiar en oauth_authlink()
:
return $oauth->getAuthorizeURL($tok['oauth_token'],true);
por:
return $oauth->getAuthorizeURL($tok['oauth_token'],false);
Solo el último parámetro cambia, que es el que indica si es una URL de autenticación o autorización. El resto es lo mismo, guardamos los tokens de acceso y procedemos con el resto de llamadas al API que necesitemos.
Pueden descargar los archivos base de este ejemplo para que lo adapten a su aplicación o empiecen a experimentar por su cuenta (también incluí varias funciones para crear y borrar las cookies con las cuales verificaran al usuario). ¿Lo quieren ver funcionando? Solo vayan a nuestra sección de descargas que usa este mismo código.
Hola..! me gusto tu theme del Visual studio?? me lo podias pasar..?
hola, yo desarrollé una clase para OAuth sencilla y fácil de usar, ¿como la puedo compartir por este medio?
Pega un link a las fuentes 😉
saludos
oye no se porque m marca error en estas lineas
include_once( ‘twitterOAuth.php’ );
oauth = new TwitterOAuth( CONSUMER_KEY, CONSUMER_SECRET );
y no me deja avanzar esque soy nuevo en php
Hola buenas noches, alguien me puede orientar como incorporar feebock y tiwiter a dreamweaber
Tengo una aplicación para Twitter que funciona en el navegador. No es pública. Está en mi casa. No está en ningun servidor. La hice con HTML5, CSS, javascript y PHP. Usa AJAX para comunicarse con PHP. Hasta hace poco funcionaba bien. Solo necesitaba darle login/password. Cuando Twitter se mudó definitivamente al OAuth dejó de funcionar. El código no importa. Solo hay que escribir algunas cosas con el OAuth de Abraham. Tuve que registrarla en el API de Twitter que solo tiene dos opciones:
1) Si la registra como ‘Browser’ te pide el URL del sitio lo cual en mi caso no tiene sentido porque no hay acceso desde afuera a la computadora de mi casa. Puse el de la UCV (ver arriba) solo para lograr el registro. Por supuesto que no ha podido funcinar.
2) La otra opción es ‘Desktop’ lo cual no es el caso.
El caso es que antes tenía mi aplicación funcionando para mi y algun amigo que había copiado el código.
La pregunta clave es:
¿ Hay alguna manera de usar el OAuth desde una aplicación que funciona en un ‘browser’ privado ?. Es decir, no hay un URL para la aplicación.
Gracias. La información que proveen es excelente.
Interesante artículo, quizás aplique el registro con twitter ya que tenía con facebook y resulto dando problemas, así que termine quitandolo.
buenas por que dices al principio que los datos de token deben ser privados que pueden hacer si me roban esos datos lo que pasa que se lo he dado a una persona que me los pidio y no se que es capaz de hacer
por favor contesteme alguien
Como lograron hacer que por cada PDF que se quiera descargar se envie nos “obligue” a mandar un twit para poder hacer la descarga correspondiente? eso lo digo de la seccion de ../descargas de esta web.