Mejores prácticas para usar signInWithRedirect en navegadores que bloquean el acceso al almacenamiento de terceros

Este documento describe las mejores prácticas para utilizar inicios de sesión de redireccionamiento en navegadores que bloquean cookies de terceros. Debe seguir una de las opciones enumeradas aquí para que signInWithRedirect() funcione según lo previsto en entornos de producción, en todos los navegadores.

Descripción general

Para que signInWithRedirect() fluya sin problemas para usted y sus usuarios, el SDK de JavaScript de Firebase Authentication utiliza un iframe de origen cruzado que se conecta al dominio de Firebase Hosting de su aplicación. Sin embargo, este mecanismo no funciona con navegadores que bloquean el acceso al almacenamiento de terceros.

Debido a que pedir a sus usuarios que deshabiliten las funciones de partición de almacenamiento en el navegador rara vez es una opción, en su lugar debe aplicar una de las siguientes opciones de configuración a su aplicación, según las características específicas de su caso de uso.

  • Si aloja su aplicación con Firebase Hosting en un subdominio de firebaseapp.com , este problema no lo afecta y no es necesario realizar ninguna acción.
  • Si aloja su aplicación con Firebase Hosting en un dominio personalizado o un subdominio de web.app , use la opción 1 .
  • Si aloja su aplicación con un servicio que no sea Firebase, use la Opción 2 , la Opción 3 , la Opción 4 o la Opción 5 .

Opción 1: actualice su configuración de Firebase para usar su dominio personalizado como su authDomain

Si aloja su aplicación con Firebase Hosting usando un dominio personalizado, puede configurar el SDK de Firebase para usar su dominio personalizado como authDomain . Esto garantiza que su aplicación y el iframe de autenticación utilicen el mismo dominio, lo que evita problemas de inicio de sesión. (Si no usa Firebase Hosting, debe usar una opción diferente).

Para actualizar su configuración de Firebase para usar su dominio personalizado como su dominio de autenticación, haga lo siguiente:

  1. Configure el SDK de Firebase JS para usar su 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>"
    };
    
  2. Agregue el nuevo authDomain a la lista de URI de redireccionamiento autorizados de su proveedor de OAuth. La forma de hacerlo dependerá del proveedor, pero en general puedes seguir la sección "Antes de comenzar" de cualquier proveedor para obtener instrucciones exactas (por ejemplo, el proveedor de Facebook ). El URI actualizado para autorizar se parece a https://<the-domain-that-serves-your-app>/__/auth/handler ; el /__/auth/handler final es importante.

    De manera similar, si está utilizando un proveedor SAML, agregue el nuevo authDomain a la URL del Servicio de consumidor de aserciones (ACS) de SAML.

  3. Asegúrese de que su continue_uri esté en la lista de dominios autorizados .

  4. Vuelva a implementar 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()

Utilice signInWithPopup() en lugar de signInWithRedirect() . El resto del código de su aplicación sigue siendo el mismo, pero el objeto UserCredential se recupera de manera diferente.

API modular web

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

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

API con espacio de nombres web

  // 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 ideal para los usuarios: ocasionalmente, el dispositivo o la plataforma bloquea las ventanas emergentes y el flujo es menos fluido para los usuarios de dispositivos móviles. Si el uso de ventanas emergentes es un problema para tu aplicación, deberás seguir una de las otras opciones.

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

El flujo signInWithRedirect comienza redirigiendo desde el dominio de su aplicación al dominio especificado en el parámetro authDomain en firebase config (" .firebaseapp.com" de forma predeterminada). authDomain aloja el código auxiliar de inicio de sesión que redirige al proveedor de identidad, que, en caso de éxito, redirige nuevamente al dominio de la aplicación.

Cuando el flujo de autenticación regresa al dominio de su aplicación, se accede al almacenamiento del navegador del dominio auxiliar de inicio de sesión. Esta opción y la siguiente (para autohospedar el código) eliminan el acceso al almacenamiento entre orígenes, que de otro modo sería bloqueado por los navegadores.

  1. Configure un proxy inverso en su servidor de aplicaciones para que las solicitudes GET/POST a https://<app domain>/__/auth/ se reenvíen a https://<project>.firebaseapp.com/__/auth/ . Asegúrese de que este reenvío sea transparente para el navegador; Esto no se puede hacer mediante un redireccionamiento 302.

    Si está utilizando nginx para servir su dominio personalizado, la configuración del proxy inverso se verá así:

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

Opción 4: alojar automáticamente el código de ayuda de inicio de sesión en su dominio

Otra forma de eliminar el acceso al almacenamiento entre orígenes es autohospedar el código auxiliar de inicio de sesión de Firebase. Sin embargo, este enfoque no funciona para el inicio de sesión de Apple o SAML. Utilice esta opción sólo si la configuración de proxy inverso en la opción 3 no es factible.

Alojar el código auxiliar tiene los siguientes pasos:

  1. Descargue los archivos al 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. Aloje los archivos anteriores en el dominio de su aplicación. Asegúrese de que su servidor web pueda responder a https://<app domain>/__/auth/<filename> y https://<app domain>/__/firebase/init.json .

    A continuación se muestra una implementación de servidor de muestra que descarga y aloja los archivos. Recomendamos descargar y sincronizar los archivos periódicamente para garantizar que se obtengan las últimas correcciones de errores y funciones.

  3. Siga los pasos de la Opción 1 para actualizar redirect_uri autorizado y su authDomain . Una vez que vuelva a implementar su aplicación, el acceso al almacenamiento entre orígenes ya no debería ocurrir.

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 convenientes para envolver una lógica complicada y evitar la necesidad de involucrar otro SDK. Puede evitar el uso de cualquiera de los métodos por completo iniciando sesión de forma independiente en su proveedor y luego usando signInWithCredential() para intercambiar las credenciales del proveedor por una credencial de autenticación de Firebase. Por ejemplo, puede utilizar el SDK de inicio de sesión de Google , código de muestra para obtener una credencial de cuenta de Google y luego crear una instancia de una nueva credencial de Google ejecutando el siguiente código:

API modular web

  // `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);

API con espacio de nombres web

  // `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 haber llamado signInWithCredential() , el resto de tu aplicación funciona igual que antes.

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