Google y su Oauth2

Esta semana me ha tocado lidiar con la api de google para un proyecto y la verdad es que me ha llamado la atención el sistema que tienen para autentificarse y usar sus servicios. Me parece simplemente perfecto. Lastima que la documentación no sea así, por lo que voy a explicar un poco los pasos que hice por si a alguien le sirve de ayuda.

Antes de continuar, decir que hay dos formas para usar su api desde vuestra aplicación php. La primera es usando las clases que google ya tiene implementadas y que os podéis descargar desde su repositorio. La otra es armaros de valor y picar a pelo vuestra aplicación usando solo lo que necesitáis.

Yo personalmente recomiendo que, si tenéis tiempo, le deis un vistazo a sus clases ya que, aunque su documentación es prácticamente nula, siempre se descubren cosas interesantes o maneras de hacer las cosas.

Por desgracia, como hoy en día el tiempo es oro, yo he optado por la segunda opción que, aunque parezca menos noble, os puede ayudar a entender como funciona realmente el sistema.

Pongamos un ejemplo para mejor comprensión. Digamos que queremos poner en nuestra web un botón de login que atacara contra la api de google (ya hay códigos por la red de redes más sencillos para hacer esto pero es solo un ejemplo para entender el funcionamiento de la api de google). Para que funcione correctamente, el proceso tendría que ser más o menos el siguiente:

Gráfico del proceso de solicitud de información a la api de google

  1. El usuario hará clic en el botón de login para identificarse en nuestra aplicación web con una cuenta de google.
  2. Nuestra aplicación web solicitara a la api de google, permiso para acceder a los datos del usuario.
  3. La api de google le pedirá al usuario permiso para que nuestra web acceda a sus datos.
  4. Cuando el usuario acepte, la api de google retornara a nuestra web un código con el que solicitar un token valido.
  5. Con este código, nuestra aplicación web solicitara un token valido para poder acceder a los datos del usuario.
  6. La api de google retornara un token valido con el que poder hacer consultas
  7. Nuestra aplicación web solicitara los datos del usuario pasando el token devuelto antes.
  8. La api de google retornara los datos del usuario.
  9. Y con esto habrá acabado el proceso. En la imagen lateral se puede ver un gráfico del proceso para mejor comprensión.

Bueno, después de este rollo vamos al grano. Para poder realizar el anterior proceso descrito, primero tendréis que registrar vuestra aplicación en google (el proceso es muy similar al que hay que hacer para registrar una aplicación en la api de facebook pero google, aunque parezca mentira, no pone tantas trabas como facebook a la hora de registrar la aplicación. A diferencia de facebook, el registro es sencillo y no tiene nada de especial). Como apunte, destacar que hay que prestar especial atención a la hora de poner la url de callback, por dos motivos. El primero porque google usa ese campo (a demás de muchos otros) como campo de seguridad, que habrá que pasarle cuando solicitemos un token valido “si el callback pasado no corresponde con el que tienen ellos, os lanzaran un error”. El otro motivo es más obvio y es que sera ahí donde volverá vuestra aplicación cuando el usuario ya haya dado su consentimiento.Proceso de registro de nuestra aplicación en la api de google.

Una vez registrado necesitaremos apuntarnos, ademas del callback que hemos puesto, el client id y el client secret.

El siguiente paso es activar los servicios que necesitaremos de google. Para hacer esto hay que ir a la pestaña “services”. Una vez dentro de ella sera cuestión de activar los servicios que queramos y listo. Para la mayoría de los servicios no tendréis problemas pero para algunos en concreto (como la api de Blogger) tendréis que rellenar un formulario (como si de una visita al papa se tratase) explicando vuestras intenciones (vamos que habéis sido niños buenos y que lo vais a seguir siendo mientras uséis la api de Blogger), mientras que para otras tendreis que tirar directamente de la MasterCard (como la api de Maps) si nos pasamos con las peticiones. Mi consejo es que activéis solo los servicios que necesitéis y os leáis bien los limites que tiene cada servicio si no queréis tener sorpresas futuras (están justo al lado de cada botón de activación del servicio).Listado de servicios disponibles en la api de google.

También hay que tener en cuenta que en esta lista no aparecen todos los servicios disponibles y es que hay algunos servicios que ya están activados por defecto porque son gratuitos y no tienen ningún tipo de limitación. Por lo que solo habrá que añadirlos a la lista de servicios que nuestra aplicación va a usar y listo, pero me estoy avanzando. Este tema lo tocaremos más a delante.

Una vez tengamos registrada nuestra aplicación solo nos queda programar el proceso para obtener el token y así poder hacer consultas a la api de google si tener que estar pasandole continuamente nuestros datos de la aplicación o los datos del usuario.

Para obtener este toquen tendremos que hacer una petición GET a https://accounts.google.com/o/oauth2/auth pasandole los siguientes parámetros:

Parametro Descripción
response_type Indica a google que ha de devolver un código de autorización. Este código nos sera necesario para poder solicitar un token valido. El valor de este parámetro sera siempre “code”.
client_id El client id de nuestra aplicación. Lo hemos obtenido antes cuando hemos registrado nuestra aplicación en google.
redirect_uri La url de callback que hemos puesto cuando registramos nuestra aplicación. Tener en cuenta que si no la ponéis exactamente igual que como la habéis puesto cuando habéis registrado vuestra aplicación en google, este se quejara de que la dirección de callback no es valida y no os dejara continuar.
scope Esta sera la lista de permisos a los que google le pedirá permiso al usuario para que nuestra aplicación tenga acceso.
La verdad es que esta lista puede ser tan larga como servicios hayamos activado cuando hemos registrado nuestra aplicación pero hay algunos servicios (como por ejemplo el acceso a los datos de webmastertools) en los que no es necesario que lo activemos.
Para saber como activar cada servicio tendrás que buscar en la documentación de este, cual es el scope (identificador) del servicio y ponerlo en esta variable. Por ejemplo el servicio de analytics es el scope “https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fanalytics”
state Este campo es un string que puede contener el valor que deseemos. Este string google lo devolverá en la primera respuesta por lo que lo podemos tratar, por ejemplo, por si tenemos varios logins a google en nuestra web, saber desde que parte de nuestra web viene el usuario para poder redirigir-lo a donde nos interese. Es obligatorio poner algo por lo que no lo olvidéis.
Descargar index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
define('CLIENTID','xxxxxxxxxxxx.apps.googleusercontent.com');
define('CLIENTSECRET','xxxxxxxxxxxxxxxxxxxxxxx');
define('URLCALLBACK', 'http://xxxxx.com/googcallback.php');
define('URL','http://xxxxx.com/');
 
if (isset($_GET['error']) && $_GET['error']){
	$error = $_GET['error'];
 
	header('Location: '.URL.'error.php?errorg='.$error);
	die();
} elseif (isset($_GET['code']) && $_GET['code']) {
	$code = $_GET['code'];
 
	header('Location: '.URL.'googcallback.php?code='.$code);
	die();
} else {
	$scope = 'https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+';
	$scope .= 'https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+';
	$scope .= 'https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fanalytics.readonly+';
 
	$url = "https://accounts.google.com/o/oauth2/auth?scope=$scope&state=%2Fprofile&redirect_uri=".URLCALLBACK."&response_type=code&client_id=".CLIENTID;
 
	header('Location: '.$url);
	die();
}
?>

Una vez hayas enviado la solicitud a la api de google, si todo ha ido bien, te retornará por GET un código (en la variable code) con el que podrás solicitar un token. Para solicitar el token tendrás que hacer una peticion POST
a https://accounts.google.com/o/oauth2/token pasandole los siguientes parámetros:

Parametro Descripción
code El código devuelto por la llamada anterior. Este código es de uso único por lo que si no realizáis bien la solicitud o se corta la conexión mientras se realizaba el proceso, tendréis que volver a solicitar otro código empezando el proceso de cero.
client_id El mismo client id de antes.
client_secret El client secret obtenido cuando registramos la aplicación
redirect_uri La url de callback puesta en el registro de la aplicación.
grant_type De este campo no se especifica mucho. Simplemente que ha de tener como valor “authorization_code”

Si todo ha ido bien, la api nos enviara un fichero JSON con el token y otros atributos de este como son el tipo de token, cuando caduca y un id de este.

Realmente, el importante el es token, ya que sera el necesario para realizar consultas a la api de google. Los otros son más para si queréis realizar peticiones durante un periodo largo de tiempo (ya que el token tiene un tiempo de vida y cuando este expira, hay que volver a solicitar un nuevo token valido).

Un ejemplo de código php de solicitud de token seria el siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
define('CLIENTID','xxxxxxxxxxxx.apps.googleusercontent.com');
define('CLIENTSECRET','xxxxxxxxxxxxxxxxxxxxxxx');
define('URLCALLBACK', 'http://xxxxx.com/googcallback.php');
define('URL','http://xxxxx.com/');
 
function request_token($code){
//Solicita el token a google a con el código pasado
	$tokendata = array();
 
	$ch = curl_init('https://accounts.google.com/o/oauth2/token');
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, "code=".$code."&client_id=".CLIENTID."&client_secret=".CLIENTSECRET."&redirect_uri=".URLCALLBACK."&grant_type=authorization_code");
	curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1); 
	$result_curl = curl_exec($ch);
	$error_curl = curl_error($ch);
	curl_close($ch);
 
	$res = json_decode($result_curl);
 
	if ($res->access_token){
		$tokendata['token_access']=$res->access_token;
	}
	if ($res->token_type){
		$tokendata['token_type']=$res->token_type;
	}
	if ($res->expires_in){
		$tokendata['token_expires_in']=$res->expires_in;
	}
	if ($res->id_token){
		$tokendata['token_id']=$res->id_token;
	}
	return $tokendata;
}
 
$code='';
$param='';
$tokendata = array();
 
if(isset($_GET['code']) && $_GET['code']){
	$code = $_GET['code'];
}
 
if ($code){
	$tokendata = request_token($code);
}
?>

Y con esto ya tenemos todo lo necesario para realizar solicitudes a la api de google. Hay que tener en cuenta que todas las respuestas de la api de google son en formato JSON por lo que os recomiendo que os leáis la documentación del servicio que vais a utilizar para saber tratar las respuestas que nos puede dar.

Aquí os dejo un ejemplo para solicitar el correo electrónico del usuario que se ha logeado en nuestra aplicación con una cuenta de google:

Descargar googgetmail.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
define('TOKENGOOGLE','xxxxxxxxxxxx');
 
function get_userEmail($token){
	$email = '';
 
	$url = 'https://www.googleapis.com/oauth2/v1/userinfo';
	$url .= '?access_token='.$token;
 
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1); 
	$result_curl = curl_exec($ch);
	$error_curl = curl_error($ch);
	curl_close($ch);
 
	$res = json_decode($result_curl);
 
	if ($res->email){
		$email = $res->email;
	}
	return $email;
}
 
$email = get_userEmail(TOKENGOOGLE);
?>

Y esto es todo. Espero haber sido de ayuda para aquellos que estén empezando en el mundo de la api de google. Esto que he puesto aquí es solo la punta del icebeg, ya que se pueden llegar a hacer cosas muy chulas. Poco a poco iré poniendo más información pero si alguien necesita ayuda para aclarar dudas puede escribirme y le ayudare encantado.

17 pensamientos en “Google y su Oauth2

  1. Agencia marketing online

    Muy buen artículo, acabo de descubrir el blog y veo que tiene muy buenos recursos.

  2. Ruben Autor

    Gracias. Siempre intento publicar lo que voy aprendiendo en el día a día de mi trabajo, para tenerlo como apuntes y para compartirlo con quien tenga un problema similar, saber por donde atacar el problema.

  3. Jose

    Hola, soy nuevo en esto de las APIs de Google Maps

    Que tal ruben tengo unas dudas sobre la URL callback que se debe poner, es que en mi caso quiero usar las APIs de Google Maps para proyectos de mi trabajo.
    Que url debería poner?
    La URL que ponga tiene que ver con la url de proyecto web donde utilice las APIs de Google o es independiente?

    Me podrías dar tu correo para poder aclarar más fácil mis dudas

    Muy buen Post
    Saludos

    Espero puedas ayudarme

  4. Ruben Autor

    Desconozco como funciona la api de google maps, ya que todavía no he tenido tiempo de ponerme con ella (aunque espero dentro de poco poder ponerme ya que, hace poco me ha llegado un proyecto en el que tendré que usarla).

    De todos modos, si necesitas usar este método de identificación por oauth, la url de callback que has de poner es la que, en tu software, se encargara de tratar el token que te envíe google después de que el usuario, autorice a tu aplicación, el acceso a sus datos de cuenta.

    En el caso del ejemplo, seria el fichero googlecallback.php (si que es cierto que no estaban bien puestos los nombres de los ficheros. Ya los he cambiado).

    Espero que te haya ayudado con tus dudas. Si quieres contactar con migo, mi correo lo tienes en la sección de quien soy.

  5. Miguel Ángel

    Estupendo el tutorial, de los mejorcitos que he visto por el momento, solo me he quedado un poco bloqueado con el define(‘TOKENGOOGLE’,’xxxxxxxxxxxx’); que no sabía que poner, para los que estén como yo solo hay que cambiar las ‘xxxxxxxxxxxx’ por $tokendata[‘token_access’] y listo, en mi aplicación lo manejo todo desde la misma pagina index de la siguiente manera si entras y no estas conectado muestra el botón de conectar con google y muere, si sí estas conectado con google hace un include del callback y posteriormente utilizo el código de googgetmail.php para sacar todos los datos que necesito del usuario

    Saludos

  6. ]JoseLuis

    ¿Cómo hago para implementar esta función en mi propio formulario HTML_QuickForm?

    ¿es posible? Gracias de antemano.

  7. Alejandro Valdivia

    Hola soy nuevo en esto y la verdad me parece super este tutorial pero necesito saber si me pueden ayudar más, resulta que necesito sacar todos los datos del usuario (EMAIL, Fecha del EMAIL etc) me pueden ayudar por favor.

  8. Alejandro Valdivia

    Rubén, me puedes ayudar un poco ya que soy nuevo en esto…. mostrando el código para identificar bien los llamados ya que no me funca…

    Gracias

  9. Tomás Alejandro

    Hola Rubén.. muy buen tutorial.. pero, tengo una duda..
    Al darle a acepto, me da error.. mira, hice lo siguiente..
    1- Coloqué los archivos index.php y googcallback.php en mi public_site
    2- Cree la carpeta callback, que es mi redirect_url..

    ¿Que me falta? supongo que algo donde se guarden los datos.. no se!! ayuda

  10. Ruben Autor

    Hola Tomás

    Recuerda que has de registar tu aplicación en google y, en el caso del ejemplo que pongo, has de poner los datos de acceso en las constantes de los ficheros.

  11. Ruben Autor

    Hola Jorge.

    ¿¿¿Utilizar su cuenta??? Con la api de google podrás obtener información de un usuario. No lo he investigado en profundidad pero dudo que permitan realizar acciones en nombre de un usuario. ¿Que es lo que tienes en mente?

  12. Sisco

    Hola Ruben, como verás mi web es la de un instituto de secundaria. Hasta ahora los alumnos se autentifican con un nombre de usuario y contraseña que les facilitamos al comenzar el curso.
    Hace poco que nos hemos adherido al google apps, así todos los alumnos y profesores tienen una cuenta de correo alumno@institutlasegarra.cat.
    Pregunta: todo lo que explicas, sirve para poder autentificarse en la web del instituto con la cuenta de correo y así dejar de gestionar el acceso a la intranet con el nombre de usuario y contraseña como hacemos hasta ahora?
    Ya ves, que quizás mis recursos técnicos no son muy elevados, pero hacemos lo que podemos.
    Un saludo
    Sisco

  13. Ruben Autor

    Hola Sisco.

    Si que te serviría aunque, si solo lo necesitas para hacer el login, existen códigos más sencillos de utilizar que te harán esa función. Esto esta más pensado para usar los servicios que ofrece Google, como la api de google Maps, o el acceder a los datos de tu cuenta de analytics o webmastertools.

    Me suena que en la “escasa” documentación de Google, hay un generador de códigos para hacer esto que pides.

    Lo encontré. Aquí la tienes https://developers.google.com/+/web/signin/?hl=es

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *