Cómo usar una API de Google con autenticación a través de OAuth2
¿Qué es Google OAuth2?
El uso de las aplicaciones cloud de Google está ampliamente aceptado y extendido. Queda atrás el tiempo en el que los que usaban Gmail eran esos frikis que habían dejado de conectarse al messenger.
Ya nadie te mira mal si le dices que le vas a compartir un documento en Google Drive, es más, ahora son los propios clientes los que te vienen con la idea de integrar alguno de sus servicios o productos con algunos de los servicios que ofrece Google.
Bueno pues ahí es donde nos vamos a situar, pues el primer paso para la integración con alguno de los servicios Google es, claro está, avisar a Google de que los vamos a usar.
Si accedemos a la documentación técnica de Google OAuth2[1] el mismo título nos indica que se trata de un mecanismo de autenticación y autorización que nos permite usar las APIs de Google.
Nota: El paradigma de autenticación/autorización es un concepto importante que se manejará a lo largo de este post, por lo que si no sabes muy bien la diferencia, puedes leerte esta página[2].
Alta de tu aplicación en Google
Nada más y nada menos. Para poder hacer uso de cualquier servicio de Google, debes dar de alta tu aplicación (ya sea una aplicación web, una aplicación móvil, o un bot).
Para ello debes acceder a la consola de desarrolladores Google (Google Developers Console[3]) y crear un nuevo proyecto:
Una vez añadido, añadimos las APIs que queramos (en nuestra prueba, Google Drive):
Con esto tenemos habilitado el acceso a las APIS que queramos usando este proyecto. Sin embargo, nos falta dar de alta los clientes que lo vayan a usar, es decir, la web o la aplicación móvil en cuestión.
Para ello, seleccionamos el menú de credenciales (Credentials) y seleccionamos la opción de crear un nuevo cliente:
Aquí es donde le decimos que tipo de cliente queremos crear:
- Aplicación web: Cualquier web que valla a hacer uso de los serivicios de Google usando credenciales de usuarios.
- Cuenta de servicio: Esta cuenta se usa generalmente para el acceso a datos de una cuenta específica del servicio, es decir, no requiere autenticación u autorización del usuario de la aplicación
- Aplicación instalada: Aplicación instalada a nivel de SO (realmente para Android o IPhone)
Como la prueba la vamos a hacer desde una web, le tenemos que especificar la url. La prueba está alojada en github[4] y no tendremos URL de retorno para la autorización (la leeremos por post), por tanto la configuración correcta es:
- AUTHORIZED JAVASCRIPT ORIGINS -> http://alediator.github.io
- AUTHORIZED REDIRECT URIS -> http://alediator.github.io/gapi-ext
A este nivel ya queda de mano del desarrollador el permitir el acceso desde distintas URLs para un mismo cliente o generar distintos clientes por cada URL que vaya a acceder.
Pantalla de permisos
Antes de entrar en materia, necesitarás configurar la pantalla de consentimiento de tu proyecto.
Desde la misma consola de desarrolladores de Google:
Es necesario configurar al menos el nombre y el email, de lo contrario Google nos devolverá un error al intentar autorizar a nuestra aplicación.
El flujo de Google OAuth2
Si has llegado hasta aquí te estarás preguntando: ¿eso es todo? ¿tan fácil es? bueno pues sí y no.
Me explico, hasta aquí todo es relativamente sencillo, a partir de aquí es donde entra la magia negra y la confianza ciega, pues, si bien existe documentación al respecto, a mi entender es algo confusa y corta.
En el caso que nos ocupa[5], el flujo que sigue la autenticación es:
Y como podéis apreciar, aparecen una serie de conceptos a tener en cuenta dentro de este flujo:
Authorization code
Es una cadena de texto que nos devolverá Google, pero que no nos permite acceder a sus servicios, sino solicitar el token (access o refresh)
Token
Se trata de una cadena larga con un hash que nos devolverá Google. A su vez se dividen en:
Access Token
Token que servirá para un acceso normal de nuestra aplicación a los servicios. Generalmente caducará a la hora de ser expedido.
Refresh Token
Token que permitirá generar access tokens posteriormente de forma que nuestra aplicación no nos pedirá más permiso.
Este tipo de token se generará una única vez por par cliente/servicio(s) (o client_id/scope(s)) a no ser que se revoque.
¿Cómo? Pues que si pedimos permiso para acceder a Google Drive de forma offline y luego pedimos permiso para acceder a Google Drive y a GMail al mismo tiempo, Google nos devolverá dos refresh token válidos y diferentes, pero si repetimos cualquiera de estas peticiones Google no nos devolverá ningún refresh token, por lo que tenemos que guardar el refresh token que nos de y revocarlo en caso de ser inservible siempre.
¿Y cuando se revoca? La documentación de Google al respecto[6] nos dice que dependiendo de la cantidad de tokens que pida nuestra aplicación, empezará a caducar los antiguos. Además, podremos revocar un token desde nuestra aplicación o revocarlo el propio usuario desde la configuración de seguridad de su cuenta Google[7]; por lo que tendremos que tener en cuenta estos supuestos al modelar la integración.
Integración de una aplicación web para acceso online
La integración más sencilla a nivel conceptual es la que realizaremos de forma online, es decir, contaremos con que el usuario tendrá una sesión abierta con su cuenta Google en el navegador.
A este nivel podemos:
- Construir las peticiones a Google de forma manual
- Hacer uso del cliente beta Javascript[8]
En nuestro caso hemos optado por la segunda opción.
Google APIs Client for Javascript en detalle
Esta librería forma parte de la masa oscura de Google. Quiero decir con esto, que busques lo que busques no encontrarás ningún código fuente y si pretendes depurarla, prepárate para tener la consola Javascript comiéndose toda tu RAM formateando el javascript comprimido e ilegible.
Encontrarás mucha documentación de uso y muchos ejemplos (incluso oficiales[9]), pero a la hora de buscar un error en el flujo de autenticación (que probablemente será tuyo) te volverás loco intentando bajar a las tripas.
Mis únicos consejos a este nivel son:
- Tened claro el flujo que seguirá tu aplicación respecto a la autorización/autenticación y uso de servicios de Google
- Empezad por algo sencillo, es decir, si, por ejemplo, vas a usar Google Drive, empieza por about y ya te complicarás listando directorios o subiendo ficheros.
- Armaros de paciencia y observad las peticiones que se van montando desde la API con la consola Javascript.
Con propósito de hacer una demostración al respecto, he preparado una página de demostración que permite:
- Pedir permisos a Google para uno de sus servicios
- Mostrar la información básica del usuario (actualmente sólo para Google Drive a través del servicio about[10])
Para verla en acción sencillamente accede a: http://alediator.github.io/gapi-ext/ y pulsa en ‘Start demo’.
¿Te interesa la API de Google? Conoce los nuevos términos del servicio y políticas de desarrollo en YouTube API Services
¿Tienes alguna duda o quieres contarnos tu proyecto? No lo dudes y ponte en contacto con nosotros para cualquier cuestión.
Referencias
- [1] https://developers.google.com/accounts/docs/OAuth2
- [2] http://es.wikipedia.org/wiki/Autenticaci%C3%B3n
- [3] https://console.developers.google.com
- [4] http://alediator.github.io/gapi-ext
- [5] https://developers.google.com/accounts/docs/OAuth2WebServer
- [6] https://developers.google.com/accounts/docs/OAuth2WebServer#refresh
- [7] https://security.google.com/settings/security/permissions
- [8] https://developers.google.com/api-client-library/javascript/start/start-js
- [9] https://github.com/google/google-api-javascript-client
- [10] https://developers.google.com/drive/v2/reference/about