Verificación de token ID Firebase en un servicio RESTful creado con PHP

portada_verificaciontokens

 

Hola a tod@s,

En este primer artículo de mi blog y de la categoría de artículos “consumo de servicios RESTful desde Android” vamos a ver como podemos verificar un token de Firebase enviado desde una app Android en un webservice RESTful programado en lenguaje PHP.

 

¿Para qué sirve esto?

Si tu app de Firebase se comunica con un servidor de backend personalizado, podría ser necesario que se identifique al usuario con sesión activa actualmente en el servidor. Según la documentación oficial de Firebase  la manera segura de hacerlo es enviando el token de ID a tu servidor usando HTTPS después de que el usuario inicie sesión con éxito. Luego, en el servidor, se verifica la integridad del token y se pueden recuperar los datos contenidos por el mismo, por ejemplo para utilizar el ID único de usuario del token  para identificar de manera segura en el backend al usuario con sesión iniciada.

Para verificar un token de ID con el Firebase Server SDK,  Firebase nos proporciona de manera oficial para JAVA y NODE.js  el método verifyIdToken.  Con este método si el token de ID no caducó y está firmado de manera adecuada, será decodificado.

Hasta aquí todo esto lo podemos ver muy bien documentado en el siguiente enlace.

 

¿Cuál es el problema?

El problema que yo me encontré queriendo implementar esta seguridad en una de mis apps, fue que el webservice con el que yo estoy conectando la app en cuestión está programado en lenguaje PHP y como podemos observar no hay ningún método nativo en Firebase por el momento para verificar tokens en este lenguaje.

 

¿Solución?

Sin embargo, buscando en la documentación de Firebase en inglés encontré información sobre cómo verificar tokens ID de Firebase en caso de que el lenguaje de tu webservice no esté soportado

oficialmente por el Firebase server SDK y la forma de hacerlo es utilizar la librería de terceros JWT library (esta información no está disponible en la página de Firebase traducida al español).

verify_jwt_firebase

 

Implementación.

Diagrama de verificación de token ID Firebase en webservice para aumentar seguridad en las operaciones sobre la BD.

diagram_verify_token

 

1.Autentificar usuario en Firebase Server.

Como podemos observar en el diagrama, la primera operación que tendríamos que realizar es inciar sesión correctamente en Firebase Server desde nuestra app Android para poder recoger el token ID del usuario actual de Firebase desde esta y enviarlo posteriormente al webservice para su verificación.

Para realizar este primer paso deberíamos tener implementado un sistema de login con Firebase Authentication SDK en nuestra app. El objeto de este artículo no es explicar como implementar un login con Firebase Authentication en Android, pero si tenéis dudas sobre como hacerlo os recomiendo que echéis un vistazo a la documentación oficial, o a este magnífico artículo en español publicado en Hermosa Programación por James Revelo.

 

2.Recoger token ID de Firebase en la app y enviarlo al webservice para su verificación.

Una vez el usuario a iniciado sesión con éxito en Firebase Server podemos proceder a recoger el token ID desde nuestra app para enviarlo al webservice mediante una llamada HTTP para su verificación.

A continuación se muestra un fragmento del código que podríamos utilizar para realizar esta tarea. En primer lugar se recoge el usuario actual con los métodos getInstance()  y  getCurrentUser() del Firebase SDK y posteriormente se recoge el token ID del usuario que nos proporciona Firebase,  añadiendo un listener al método getToken() que queda en escucha para realizar la llamada HTTP al webservice enviando el token ID recogido una vez finalizada la tarea.

 

Nota: Es recomendable que se verifique manualmente el token obtenido en la siguiente web antes de continuar.

verify_jwt_firebase2

 

Para ilustrar un poco más este ejemplo vamos a suponer que la llamada HTTP de este caso sería una llamada al método POST que se realizaría utilizando la librería Retofit y que tendría el siguiente formato:

 

3. Verificación de token ID en servicio RESTful programado con PHP

Si la petición POST realizada desde el cliente Android a través del método enviaRegistro se ha culminado con éxito, ahora sería la función del webservice decodificar el token ID recibido y realizar las verificaciones oportunas para autorizar o no la inserción del nuevo registro en la BD.

En primer lugar tendríamos que preparar nuestro webservice PHP para poder decodificar el token, añadiendo la librería recomendada por Firebase  JWT library.

Como se indica en las instrucciones de la librería podemos añadirla al proyecto utilizando Composer.

Con Composer instalado en nuestro equipo nos situamos en la ruta del  proyecto del webservice y añadimos la dependencia de la librería JWT library desde la línea de comandos.

 

Con esto, nuestro webservice ya debería estar configurado para poder decodificar y verificar el token enviado desde la app Android.

Procedemos a recibir el token y el payload enviados desde el cliente Android en la función post de la clase Registros.php de nuestro servicio RESTful. Es necesario que la clase Registros.php herede de la clase JWT.php de la librería.

 

Se realiza una llamada al método verifyToken de la clase registros.php y si este verifica la integridad del token se procede a la inserción del nuevo registro en la BD y se devuelve un código de éxito, de lo contrario se devolverá un código 401 de no autorizado.

 

El método verifytoken es el encargado de decodificar y verificar el token recibido mediante el siguiente proceso:

  1. Primero se recogen las claves públicas proporcionadas por Google en esta url. Según la documentación oficial de Firebase todos los tokens ID generados por Firebase se deberían poder decodificar utilizando alguna de las keys que se proporcionan en esa dirección.
  2. Se recoge el objeto Json que devuelve la llamada a la url, se parsea y se guardan todas las keys proporcionadas en un array (siempre hay solamente 3 o 4 keys).
  3. Se va probando a decodificar el token con cada una de las claves recogidas, hasta que se encuentra la correcta. El algoritmo criptográfico utilizado por Firebase es el  “RS256”  por lo que lo utilizamos para decodificar el token JWT.
  4. Una vez decodificado el token podemos acceder a sus atributos. En el caso del ejemplo casteamos el token JWT decodificado como array y accedemos a sus atributos a través del nombre de los claims. Según la documentación oficial estos son los JWT claims que podríamos utilizar  para realizar la verificación del usuario en nuestro servidor.

atributos_token

 

En este código podemos ver el método verifytoken y como para la verificación del token comprobamos que el valor de “aud” corresponde con el id de nuestro proyecto en Firebase. Una vez realizada esta comprobación con éxito se verifica si el “uid” del token existe también dentro de nuestra nuestra BD.

 

En el método checkUIDenBD se utilizaría una sentencia como esta para verificar la existencia del “uid” de Firebase en nuestra BD.

 

Esto implica que para que la verificación se realice con éxito se debería haber guardado el “uid” de Firebase en nuestra BD cuando se dio de alta al usuario en este servicio.

 

Conclusión.

En mi opinión utilizar el Firebase Authentication SDK como parte de la seguridad de nuestras apps es una muy buena opción para ahorrar tiempo y muchos de los quebraderos de cabeza que supone crear un sistema de login propio en nuestro servidor. Además de tener otras ventajas como admitir la autenticación con proveedores como Google, Facebook y Twitter, etc., o poder aprovechar su potencial para integrar con sencillez otras funcionalidades del SDK de Firebase como las Notificaciones Push.

En este artículo hemos visto como podemos aumentar la seguridad con Firebase no limitándose solo la identificación del usuario en Firebase Server desde la app Android, si no extendiéndola también a las tareas que realizamos a través de nuestro webservice.

Si tienes un webservice RESTful programado en PHP y te limitaba la falta de soporte oficial de Firebase para la verificación de tokens en ese lenguaje, ya has visto como puedes llevarla a cabo utilizando la librería JWT.

Espero que este artículo os haya resultado interesante y que no seáis demasiado duros conmigo pues es mi primer artículo en el blog  😉

Quedo abierto a cualquier tipo de sugerencia, observación o propuesta. Tenéis disponibles los comentarios y las redes sociales para comunicaros conmigo.

Si os parece útil este tipo de artículos no dudéis en suscribiros al blog para que os lleguen las novedades por correo electrónico.

En las próximas semanas tengo pensado seguir compartiendo con vosotros artículos que tratarán sobre consumo de APIs RESTful y diseño UI en Android.

 

¡Un saludo a tod@s!


Jorgefc82

Android developer y creador del blog dedicado a la programación Android CodeToCode. Eterno aprendiz. Pienso que antes de trabajar es necesario creer en lo que se va a hacer y disfrutar con ello