En mi aplicación Firebase, me gustaría conocer la forma recomendada de realizar una solicitud del lado del servidor a Cloud Storage para Firebase en nombre de un usuario que inició sesión (autenticado a través del token de ID), con reglas de seguridad aplicadas a la solicitud (es decir, no con el SDK de administrador).
El flujo general de la aplicación actualmente se ve así:
x-forwarded-authorization (que contiene el token de ID proporcionado originalmente por el cliente) reenviado por la puerta de enlace API para luego realizar una solicitud a la API REST de Firestore , de modo que la solicitud pueda ser evaluada por reglas de seguridadPara Cloud Storage , me gustaría hacer algo similar al caso anterior de Firestore, pero no hay una API REST específica de Firebase disponible en los documentos. Es posible dejar que el cliente realice solicitudes directamente a Firebase (como se sugiere en esta respuesta ), pero preferiría mantener la lógica en el backend.
¿Hay alternativas a hacer esto para el almacenamiento? No dude en señalar también si hay mejores formas de manejar los casos de Firebase Auth y Firestore mencionados anteriormente. ¡Gracias!
EDITAR: Agregar más soluciones posibles a medida que las encuentro
auth=IDTOKEN a la API REST de Firebase:Una vez que tenga un token de ID, puede pasarlo a la API REST a través del parámetro de consulta de autenticación para autenticar una solicitud. La solicitud respeta las reglas de seguridad de Firebase como si el usuario final iniciara sesión en el cliente estuviera realizando la solicitud.
No hay forma de hacer cumplir las reglas de seguridad de Firebase para Cloud Storage cuando se usa Admin SDK. Firebase no proporciona una API REST documentada para Cloud Storage y dudo que la API REST de Google Cloud para almacenamiento acepte tokens de ID de Firebase.
Entonces, realmente no creo que tenga buenas opciones para hacer esto desde el servidor en nombre de sus usuarios. Las dos opciones que se me ocurren:
Edición 6 de enero de 2020: este método ha tenido un par de días de prueba bajo carga pesada. Consulte la parte inferior para ver algunos requisitos nuevos menores.
Respuesta original: esta no es una respuesta, sino una solución alternativa dentro del ecosistema (¡eso funciona para mí!)
Básicamente, tengo un caso de uso similar con respecto a un dispositivo iot sin conexión primero/potencialmente inseguro que necesita acceso de almacenamiento basado en autenticación con reglas de seguridad. Esta mañana eché un vistazo al repositorio SDK de Firebase js y noté que una API XHR nativa es la pieza principal que falta en la implementación de un nodo de trabajo.
Detallé mi solución en este problema de github ... incluido aquí por conveniencia:
.. parchear la biblioteca de almacenamiento con un polyfill XHR en realidad parece funcionar (Nodo 15 / pruebas mínimas hasta ahora). Específicamente, instalé xmlhttprequest-ssl y lo importé en la parte superior del módulo de almacenamiento (en mi caso, la línea 5 en
@firebase/storage/dist/index.cjs.js):
var XMLHttpRequest = require("xmlhttprequest-ssl").XMLHttpRequest;De vuelta en la aplicación, importo
firebase/storagecomo de costumbre, luego solo cargo los archivos del sistema de archivos local y los cargo según la API estándar de Firebase:
import { firebase } from "@firebase/app"; import "@firebase/storage"; /* include Firebase setup, etc. */ const filename = 'offline-user-generated-image.jpg'; const file = fs.readFileSync(filename); // for brevity only const ref = firebase.storage().ref().child(`test/${filename}`); // use the buffer's underlying arraybuffer ref.put(file.buffer, { contentType: 'image/jpg', // defaults to 'application/octet-stream' customMetadata: { uid: 'abc123', // for enhanced security rules }, }) .then(() => console.log('done')) .catch(e => console.log(e));Las reglas de almacenamiento se aplican a las cargas (¡guau!) y los tokens de seguridad y los metadatos personalizados se aplican como se esperaba. También probado con `putString'. Esto resuelve algunas soluciones alternativas bastante drásticas para mi caso de uso, ya que significa que puedo mantener mi lógica/autorización/etc. completamente dentro del ecosistema de Firebase. Ganas de escuchar los pensamientos de los demás.
Nota: Estoy usando el paquete de parches para asegurar que el parche permanezca intacto durante las instalaciones/actualizaciones.
Actualización 6 de enero de 2020: algunas piezas adicionales
Resulta que hay un tiempo de espera no aclarado en el paquete de almacenamiento que causa problemas con los procesos de los nodos (y es probable que consuma recursos en todos los entornos). He enviado un PR (prácticamente un clearTimeout ) que resuelve el problema, pero mientras tanto, esto también deberá parchearse manualmente a menos que pueda process.exit(0) en su código.
Después de considerar las diversas opciones anteriores (¡gracias Frank y som!), la mejor opción en mi situación fue cambiar las cosas y realizar solicitudes de almacenamiento directamente desde el cliente . Las 2 razones principales fueron:
Al realizar la solicitud del cliente, la respuesta anterior de som y esta respuesta pueden ser útiles si hay un error XMLHttpRequest is not defined