Práticas recomendadas para usar signInWithRedirect em navegadores que bloqueiam o acesso ao armazenamento de terceiros

Este documento descreve as práticas recomendadas para usar logins de redirecionamento em navegadores que bloqueiam cookies de terceiros. Você deve seguir uma das opções listadas aqui para que signInWithRedirect() funcione conforme pretendido em ambientes de produção, em todos os navegadores.

Visão geral

Para tornar o fluxo signInWithRedirect() perfeito para você e seus usuários, o SDK JavaScript do Firebase Authentication usa um iframe de origem cruzada que se conecta ao domínio do Firebase Hosting do seu aplicativo. No entanto, este mecanismo não funciona com navegadores que bloqueiam o acesso ao armazenamento de terceiros.

Como pedir aos usuários que desativem os recursos de particionamento de armazenamento no navegador raramente é uma opção, você deve aplicar uma das seguintes opções de configuração ao seu aplicativo, dependendo das especificidades do seu caso de uso.

  • Se você hospedar seu aplicativo com o Firebase Hosting em um subdomínio de firebaseapp.com , você não será afetado por esse problema e nenhuma ação será necessária.
  • Se você hospeda seu aplicativo com o Firebase Hosting em um domínio personalizado ou subdomínio de web.app , use a Opção 1 .
  • Se você hospedar seu aplicativo com um serviço diferente do Firebase, use a Opção 2 , a Opção 3 , a Opção 4 ou a Opção 5 .

Opção 1: atualize sua configuração do Firebase para usar seu domínio personalizado como seu authDomain

Se você estiver hospedando seu aplicativo no Firebase Hosting usando um domínio personalizado, poderá configurar o SDK do Firebase para usar seu domínio personalizado como authDomain . Isso garante que seu aplicativo e o iframe de autenticação usem o mesmo domínio, o que evita problemas de login. (Se você não usa o Firebase Hosting, precisará usar uma opção diferente.)

Para atualizar a configuração do Firebase para usar seu domínio personalizado como domínio de autenticação, faça o seguinte:

  1. Configure o SDK JS do Firebase para usar seu domínio 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. Adicione o novo authDomain à lista de URIs de redirecionamento autorizados do seu provedor OAuth. Como você fará isso dependerá do provedor, mas em geral você pode seguir a seção "Antes de começar" em qualquer provedor para obter instruções exatas (por exemplo, o provedor Facebook ). O URI atualizado para autorização é semelhante a https://<the-domain-that-serves-your-app>/__/auth/handler — o final /__/auth/handler é importante.

    Da mesma forma, se você estiver usando um provedor SAML, adicione o novo authDomain ao URL do SAML Assertion Consumer Service (ACS).

  3. Certifique-se de que seu continue_uri esteja na lista de domínios autorizados .

  4. Reimplante com o Firebase Hosting, se necessário, para buscar o arquivo de configuração do Firebase mais atualizado hospedado em /__/firebase/init.json .

Opção 2: mudar para signInWithPopup()

Use signInWithPopup() em vez de signInWithRedirect() . O restante do código do seu aplicativo permanece o mesmo, mas o objeto UserCredential é recuperado de forma diferente.

API modular da 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 com namespace da 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());
```

O login pop-up nem sempre é ideal para usuários: os pop-ups são ocasionalmente bloqueados pelo dispositivo ou plataforma e o fluxo é menos tranquilo para usuários móveis. Se o uso de pop-ups for um problema para seu aplicativo, você precisará seguir uma das outras opções.

Opção 3: solicitações de autenticação de proxy para firebaseapp.com

O fluxo signInWithRedirect começa redirecionando do domínio do seu aplicativo para o domínio especificado no parâmetro authDomain na configuração do firebase (" .firebaseapp.com" por padrão). authDomain hospeda o código auxiliar de login que redireciona para o provedor de identidade, que, em caso de sucesso, redireciona de volta para o domínio do aplicativo.

Quando o fluxo de autenticação retorna ao domínio do seu aplicativo, o armazenamento do navegador do domínio auxiliar de login é acessado. Esta opção e a seguinte (para auto-hospedar o código) eliminam o acesso ao armazenamento de origem cruzada, que de outra forma seria bloqueado pelos navegadores.

  1. Configure um proxy reverso em seu servidor de aplicativos para que as solicitações GET/POST para https://<app domain>/__/auth/ sejam encaminhadas para https://<project>.firebaseapp.com/__/auth/ . Certifique-se de que esse encaminhamento seja transparente para o navegador; isso não pode ser feito por meio de um redirecionamento 302.

    Se você estiver usando o nginx para servir seu domínio personalizado, a configuração do proxy reverso será semelhante a esta:

    # reverse proxy for signin-helpers for popup/redirect sign in.
    location /__/auth {
      proxy_pass https://<project>.firebaseapp.com;
    }
    
  2. Siga as etapas na Opção 1 para atualizar redirect_uri autorizado, o URL ACS e seu authDomain . Depois de reimplantar seu aplicativo, o acesso ao armazenamento de origem cruzada não deverá mais acontecer.

Opção 4: hospedar automaticamente o código auxiliar de login em seu domínio

Outra maneira de eliminar o acesso ao armazenamento de origem cruzada é auto-hospedar o código auxiliar de login do Firebase. No entanto, esta abordagem não funciona para login da Apple ou SAML. Use esta opção somente se a configuração do proxy reverso na opção 3 for inviável.

Hospedar o código auxiliar segue as seguintes etapas:

  1. Baixe os arquivos para hospedar no local <project>.firebaseapp.com executando os seguintes 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. Hospede os arquivos acima no domínio do seu aplicativo. Certifique-se de que seu servidor web possa responder a https://<app domain>/__/auth/<filename> e https://<app domain>/__/firebase/init.json .

    Aqui está um exemplo de implementação de servidor que baixa e hospeda os arquivos. Recomendamos baixar e sincronizar os arquivos periodicamente para garantir que as correções de bugs e recursos mais recentes sejam obtidos.

  3. Siga as etapas da Opção 1 para atualizar redirect_uri autorizado e seu authDomain . Depois de reimplantar seu aplicativo, o acesso ao armazenamento de origem cruzada não deverá mais acontecer.

Opção 5: lidar com a entrada do provedor de forma independente

O SDK do Firebase Authentication fornece signInWithPopup() e signInWithRedirect() como métodos convenientes para agrupar lógica complicada e evitar a necessidade de envolver outro SDK. Você pode evitar o uso de qualquer um dos métodos fazendo login de forma independente no seu provedor e, em seguida, usando signInWithCredential() para trocar as credenciais do provedor por uma credencial do Firebase Authentication. Por exemplo, você pode usar o SDK de login do Google , código de amostra para obter uma credencial de conta do Google e, em seguida, instanciar uma nova credencial do Google executando o seguinte código:

API modular da 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 com namespace da 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);

Depois de chamar signInWithCredential() , o restante do seu aplicativo funciona da mesma forma que antes.

As instruções para obter uma credencial Apple estão aqui .