Prácticas recomendadas para usar signInWithRedirect en navegadores que bloquean el acceso al almacenamiento de terceros

En este documento se describen las prácticas recomendadas para usar los inicios de sesión con redirección en navegadores que bloquean las cookies de terceros. Para que signInWithRedirect() funcione correctamente en entornos de producción y en todos los navegadores, debes seguir una de las opciones que se indican aquí.

Información general

Para que el flujo de signInWithRedirect() sea fluido para ti y tus usuarios, el SDK de JavaScript de Firebase Authentication usa un iframe entre orígenes que se conecta al dominio de Firebase Hosting de tu aplicación. Sin embargo, este mecanismo no funciona con los navegadores que bloquean el acceso al almacenamiento de terceros.

Como rara vez es una opción pedir a los usuarios que inhabiliten las funciones de partición de almacenamiento en el navegador, debes aplicar una de las siguientes opciones de configuración a tu aplicación, en función de las características específicas de tu caso práctico.

  • Si alojas tu aplicación con Firebase Hosting en un subdominio de firebaseapp.com, este problema no te afectará y no tendrás que hacer nada.
  • Si alojas tu aplicación con Firebase Hosting en un dominio personalizado o en un subdominio de web.app, usa la opción 1.
  • Si alojas tu aplicación con un servicio que no sea Firebase, usa la opción 2, la opción 3, la opción 4 o la opción 5.

Opción 1: Actualiza tu configuración de Firebase para usar tu dominio personalizado como authDomain

Si alojas tu aplicación con Firebase Hosting mediante un dominio personalizado, puedes configurar el SDK de Firebase para que use tu dominio personalizado como authDomain. De esta forma, te aseguras de que tu aplicación y el iframe de autenticación usen el mismo dominio, lo que evita el problema de inicio de sesión. Si no usas Firebase Hosting, debes usar otra opción. Asegúrate de haber configurado el dominio personalizado en el mismo proyecto que usas para la autenticación.

Para actualizar la configuración de Firebase y usar tu dominio personalizado como dominio de autenticación, haz lo siguiente:

  1. Configura el SDK de JavaScript de Firebase para que use tu dominio personalizado como authDomain:

    const firebaseConfig = {
      apiKey: "<api-key>",
      authDomain: "<the-domain-that-serves-your-app>",
      databaseURL: "<database-url>",
      projectId: "<project-id>",
      appId: "<app-id>"
    };
    
  1. Añade el nuevo authDomain a la lista de URIs de redirección autorizados de tu proveedor de OAuth. El proceso dependerá del proveedor, pero, en general, puedes seguir las instrucciones de la sección "Antes de empezar" de cualquier proveedor (por ejemplo, el proveedor de Facebook). El URI actualizado para autorizar tiene este aspecto: https://<the-domain-that-serves-your-app>/__/auth/handler. Es importante que incluya el carácter /__/auth/handler al final.

    Del mismo modo, si utilizas un proveedor de SAML, añade el nuevo authDomain a la URL del servicio de consumidor de aserciones (ACS) de SAML.

  2. Asegúrate de que tu continue_uri esté en la lista de dominios autorizados.

  3. Vuelve a desplegar con Firebase Hosting si es necesario para obtener el archivo de configuración de Firebase más actualizado alojado en /__/firebase/init.json.

Opción 2: Cambiar a signInWithPopup()

Usa signInWithPopup() en lugar de signInWithRedirect(). El resto del código de tu aplicación sigue siendo el mismo, pero el objeto UserCredential se obtiene de forma diferente.

Versión web 9

  // Before
  // ==============
  signInWithRedirect(auth, new GoogleAuthProvider());
  // After the page redirects back
  const userCred = await getRedirectResult(auth);

  // After
  // ==============
  const userCred = await signInWithPopup(auth, new GoogleAuthProvider());

Versión web 8

  // Before
  // ==============
  firebase.auth().signInWithRedirect(new firebase.auth.GoogleAuthProvider());
  // After the page redirects back
  var userCred = await firebase.auth().getRedirectResult();

  // After
  // ==============
  var userCred = await firebase.auth().signInWithPopup(
      new firebase.auth.GoogleAuthProvider());
```

El inicio de sesión mediante ventanas emergentes no siempre es la mejor opción para los usuarios, ya que, en ocasiones, el dispositivo o la plataforma bloquean las ventanas emergentes y el flujo es menos fluido para los usuarios de móviles. Si tu aplicación tiene problemas con las ventanas emergentes, tendrás que seguir una de las otras opciones.

Opción 3: Enviar solicitudes de autenticación de proxy a firebaseapp.com

El flujo signInWithRedirect empieza redirigiendo desde el dominio de tu aplicación al dominio especificado en el parámetro authDomain de la configuración de Firebase (.firebaseapp.com de forma predeterminada). authDomain aloja el código auxiliar de inicio de sesión que redirige al proveedor de identidades, que, si el inicio de sesión se realiza correctamente, redirige al dominio de la aplicación.

Cuando el flujo de autenticación vuelve al dominio de tu aplicación, se accede al almacenamiento del navegador del dominio del asistente para iniciar sesión. Esta opción y la siguiente (para alojar el código por tu cuenta) eliminan el acceso al almacenamiento entre orígenes, que de lo contrario los navegadores bloquearían.

  1. Configura un proxy inverso en el servidor de tu aplicación para que las solicitudes GET y POST a https://<app domain>/__/auth/ se reenvíen a https://<project>.firebaseapp.com/__/auth/. Asegúrate de que este reenvío sea transparente para el navegador. No se puede hacer mediante una redirección 302.

    Si usas nginx para servir tu dominio personalizado, la configuración del proxy inverso será similar a esta:

    # reverse proxy for signin-helpers for popup/redirect sign in.
    location /__/auth {
      proxy_pass https://<project>.firebaseapp.com;
    }
    
  2. Sigue los pasos de la opción 1 para actualizar el redirect_uri autorizado, la URL ACS y tu authDomain. Una vez que vuelvas a implementar tu aplicación, el acceso al almacenamiento entre orígenes debería dejar de producirse.

Opción 4: Alojar por tu cuenta el código del asistente para iniciar sesión en tu dominio

Otra forma de eliminar el acceso al almacenamiento entre orígenes es alojar por tu cuenta el código de la herramienta de ayuda para iniciar sesión de Firebase. Sin embargo, este método no funciona con el inicio de sesión con Apple ni con SAML. Usa esta opción solo si la configuración de proxy inverso de la opción 3 no es viable.

Para alojar el código auxiliar, sigue estos pasos:

  1. Descarga los archivos en el host desde la ubicación <project>.firebaseapp.com ejecutando los siguientes comandos:

    mkdir signin_helpers/ && cd signin_helpers
    wget https://<project>.firebaseapp.com/__/auth/handler
    wget https://<project>.firebaseapp.com/__/auth/handler.js
    wget https://<project>.firebaseapp.com/__/auth/experiments.js
    wget https://<project>.firebaseapp.com/__/auth/iframe
    wget https://<project>.firebaseapp.com/__/auth/iframe.js
    wget https://<project>.firebaseapp.com/__/firebase/init.json
    
  2. Aloja los archivos anteriores en el dominio de tu aplicación. Asegúrate de que tu servidor web pueda responder a https://<app domain>/__/auth/<filename> y https://<app domain>/__/firebase/init.json.

    Aquí tienes una implementación de servidor de ejemplo que descarga y aloja los archivos. Te recomendamos que descargues y sincronices los archivos periódicamente para asegurarte de que se aplican las últimas correcciones de errores y funciones.

  3. Sigue los pasos que se indican en la opción 1 para actualizar el redirect_uri autorizado y tu authDomain. Una vez que vuelvas a implementar tu aplicación, el acceso al almacenamiento entre orígenes debería dejar de producirse.

Opción 5: Gestionar el inicio de sesión del proveedor de forma independiente

El SDK de Firebase Authentication proporciona signInWithPopup() y signInWithRedirect() como métodos prácticos para envolver una lógica complicada y evitar tener que usar otro SDK. Puedes evitar usar cualquiera de los dos métodos iniciando sesión de forma independiente en tu proveedor y, a continuación, usando signInWithCredential() para intercambiar las credenciales del proveedor por una credencial de Firebase Authentication. Por ejemplo, puedes usar el SDK de inicio de sesión de Google y el código de ejemplo para obtener una credencial de cuenta de Google y, a continuación, crear una instancia de una nueva credencial de Google ejecutando el siguiente código:

Versión web 9

  // `googleUser` from the onsuccess Google Sign In callback.
  //  googUser = gapi.auth2.getAuthInstance().currentUser.get();
  const credential = GoogleAuthProvider.credential(googleUser.getAuthResponse().id_token);
  const result = await signInWithCredential(auth, credential);

Versión web 8

  // `googleUser` from the onsuccess Google Sign In callback.
  const credential = firebase.auth.GoogleAuthProvider.credential(
      googleUser.getAuthResponse().id_token);
  const result = await firebase.auth().signInWithCredential(credential);

Después de llamar a signInWithCredential(), el resto de la aplicación funcionará igual que antes.

Las instrucciones para obtener una credencial de Apple se encuentran aquí.