¿Todavía es posible hacer la verificación del lado del servidor de los tokens en Firebase 3?
Generamos tokens personalizados (JWT) en un servidor que ejecuta Golang utilizando nuestro sistema de autenticación existente (usando una cuenta de servicio). El token se usa en un cliente iOS que usa
FIRAuth.auth()?.signInWithCustomToken(customToken)
Hasta allí todo funciona bien. Pero cuando pasamos el token de cliente al servidor recuperado de:
FIRUser.getTokenWithCompletion({ token, error in ..})
no podemos verificarlo El token JWT está firmado usando RS256 y tiene un header.kid que no podemos reconocer. La clave pública de la cuenta de servicio (que se usó para firmar el token personalizado) no verifica el token del cliente. ¿La clave pública es necesaria para validar el token del cliente disponible?
Sé que es posible validar tokens de clientes utilizando la llamada “verifyIdToken” en Java o Javascript, pero esperamos poder hacerlo en Golang utilizando una biblioteca JWT estándar.
Todo funcionó bien en Firebase 2 (utilizando HS256 y el secreto de Firebase).
La respuesta corta es sí. La respuesta completa es que, en la mayoría de los casos, tenemos una herramienta más adecuada ahora. Entonces, mucho depende del caso de uso que intenta resolver.
La nueva versión de SDK es bastante más poderosa, y no hemos hecho un gran trabajo al resumir las capacidades. Este parece ser un buen lugar para contrastar las herramientas disponibles y sus usos, y luego incluiré notas específicas de terceros (es decir, Go) al final.
Usar una herramienta de autenticación externa para la autenticación del cliente
El uso principal de acuñar tokens personalizados es permitir que los usuarios se autentiquen contra un mecanismo de autenticación externo / heredado que usted controla, como su servidor LDAP. El proceso básico para esto se trata aquí: iOS , Android , Web .
Básicamente, su servicio solo acuña el token JWT y lo pasa al cliente. El cliente realiza la verificación / autenticación utilizando el token personalizado que usted proporciona.
Autenticando a sus trabajadores privilegiados
Ya no es necesario usar tokens personalizados para autenticar el proceso de su servidor. Esto se hace creando una cuenta de servicio, que se cubre paso a paso en Agregar Firebase a su Servidor . Cuando termine, terminará con un archivo JSON que contiene una clave privada.
Luego, incluya las credenciales de su cuenta de servicio haciendo referencia a ese JSON utilizando el atributo firebase.initializeApp()
en firebase.initializeApp()
, ¡y ya está! Esto está documentado aquí y se ve así (ver el enlace para la versión de Java):
var firebase = require("firebase"); // Initialize the app with a service account, granting admin privileges firebase.initializeApp({ databaseURL: "https://databaseName.firebaseio.com", serviceAccount: "./serviceAccountCredentials.json" });
Emular usuarios o limitar el acceso desde un proceso de servidor
Es bastante trivial emular a un usuario o limitar el acceso (altamente recomendado) desde un proceso de servidor. En realidad, ya no necesitas acuñar un token personalizado para esto.
Esto solo requiere agregar la databaseAuthVariableOverride
en su llamada a database.initializeApp()
:
firebase.initializeApp({ databaseURL: "https://databaseName.firebaseio.com", serviceAccount: "./serviceAccountCredentials.json", databaseAuthVariableOverride: { uid: "my-service-worker-or-user-uid" } });
Validar la identidad del cliente a través de la seguridad
En primer lugar, generalmente puede evitar tratar con la verificación del lado del servidor si está utilizando Firebase Database, haciendo que su cliente escriba en la base de datos y use las reglas de seguridad para validar su identidad. Si su servidor escucha en una ruta que requiere autenticación para escribir, entonces esto ya está resuelto sin ninguna seguridad especial en el servidor.
Al modelar esto como una cola de eventos, crea una estrategia de trabajo de servidor simple, modular y escalable. Consulta firebase-queue para ver algunas excelentes herramientas de Node.js. Es compatible con 3.x.
Verificación de tokens de ID de cliente en el servidor
Si no está utilizando Realtime Database y necesita recibir tokens de clientes (por ejemplo, mediante llamadas REST) y verifica que sean válidos, puede hacerlo utilizando verifyIdToken()
como se describe aquí . Esto se vería así:
auth.verifyIdToken(idToken).then(function(decodedToken) { var uid = decodedToken.sub; });
Si luego desea autenticarse como ese usuario para escribir en la base de datos y aplicar la seguridad, debería usar la sección Emular usuarios que aparece arriba. En otras palabras, llame a initializeApp()
con una databaseAuthVariableOverride
de datosAuthVariableOverride establecida en el uid apropiado.
Tenga en cuenta que, si intenta llamar a initializeApp()
varias veces y se produce un error similar al siguiente: Error: Firebase App named '[DEFAULT]' already exists.
Puede inicializar múltiples contextos de aplicación agregando un segundo argumento a la llamada initializeApp () (por ejemplo, database.initializeApp({...}, 'asUser'+uid)
) y luego hacer referencia a esa instancia de la aplicación usando firebase.database('asUser'+uid)
.ref (…). Para leer más sobre el uso de varias instancias de aplicaciones, mira aquí .
Código de Java disponible en los enlaces de arriba. Go y otras soluciones de terceros cubiertas a continuación.
Crear un token para usar en la API REST
Michael Bleigh cubrió este escenario aquí y merece un representante para resolverlo.
Crear tokens o verificarlos a través de REST
Esto no es compatible. Lo siento.
Golang y otros: más por venir
Estamos trabajando en una biblioteca de minería y verificación de tokens Go. También vamos a agregar herramientas de Python para esto pronto también. No hay fecha de lanzamiento o estadios para esto. Mientras tanto, si desea verificar los tokens de ID de cliente sin utilizar las bibliotecas oficiales de Firebase Node.js o Java (que tienen métodos de verificación incorporados), deberá asegurarse de que el token de identificación (que es un JWT) se ajusta a lo siguiente:
alg
(algoritmo) igual a "RS256"
. aud
(audiencia) igual a su ID de proyecto de Firebase. iss
(emisor) igual a "https://securetoken.google.com/"
. sub
(sujeto) no vacía. Tenga en cuenta que este es el uid
para ese usuario de Firebase. kid
(ID de clave) que corresponde a una de las claves públicas enumeradas en https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com
. Para Go, parece que puede usar jwt-go
para descodificar y validar el token de identificación del cliente.
Well firebase no permite la verificación de custom tokens
Lo que hacen es permitir la verificación de los id tokens
de id tokens
que se generan una vez que el usuario inicia sesión utilizando tokens personalizados. Así que, como sucedió en mi caso, si pasas los tokens personalizados de Firebase a otros servicios para que se autentiquen con tu backend, ¡la responsabilidad de la verificación de token personalizada recae sobre ti! Además, el X509 cert
cuenta de servicio de google no tiene el formato adecuado. Tiene estos delimitadores \n (new line)
que no se reemplazan con nuevas líneas en los editores de texto (yo uso vim
). Por lo tanto, lo que hice fue esto:
val factory = CertificateFactory.getInstance("X.509") val certificateFile = this.getClass.getResourceAsStream(Play.current.configuration.getString("firebase.certificate").get) val publicKey = factory.generateCertificate(certificateFile).asInstanceOf[X509Certificate].getPublicKey val claimBody = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(compactJws).getBody
\n
por una nueva línea ¡Espero que ayude!