Neste documento, descrevemos as práticas recomendadas para usar logins de redirecionamento nos navegadores
que bloqueiam cookies de terceiros. Você precisa seguir uma das opções listadas aqui para que signInWithRedirect()
funcione como esperado nos ambientes de produção em todos os navegadores.
Informações gerais
Para tornar o fluxo do
signInWithRedirect()
simples para você e seus usuários, o SDK do Firebase Authentication para JavaScript usa um
iframe de origem cruzada que se conecta ao domínio do Firebase Hosting do seu app.
No entanto, esse mecanismo não funciona com navegadores que bloqueiam o acesso ao armazenamento
de terceiros.
Pedir aos usuários para desativar os recursos de particionamento de armazenamento no navegador raramente é possível. Como alternativa, implemente uma das seguintes opções de configuração no app, dependendo das especificações do caso de uso.
- Se você hospeda o app com o Firebase Hosting em um subdomínio de
firebaseapp.com
, esse problema não afeta você, e não é preciso fazer nada. - Se você hospeda seu app com o Firebase Hosting em um domínio personalizado ou em um subdomínio de
web.app
, use a Opção 1. - Se você hospeda o app com um serviço que não é o Firebase, use a Opção 2, 3, 4 ou 5.
Opção 1: atualizar a configuração do Firebase para usar o domínio personalizado como o authDomain
Se você estiver hospedando seu app com o Firebase Hosting usando um domínio personalizado,
configure o SDK do Firebase para usar seu domínio personalizado como o authDomain
. Isso
garante que o app e o iframe de autenticação usem o mesmo domínio, o que impede
o problema de login. Se você não usa o Firebase Hosting, é preciso usar uma
opção diferente. Verifique se você configurou o domínio personalizado no mesmo
projeto que você está usando para autenticação.
Para atualizar sua configuração do Firebase e usar seu domínio personalizado como domínio de autenticação, faça o seguinte:
Configure o SDK do Firebase para JavaScript 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>" };
Adicione o novo
authDomain
à lista de URIs de redirecionamento autorizados do provedor OAuth. O modo de fazer isso depende 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 do Facebook). O URI atualizado para autorização é semelhante ahttps://<the-domain-that-serves-your-app>/__/auth/handler
, e/__/auth/handler
no final é importante.Da mesma forma, se você estiver usando um provedor SAML, adicione o novo
authDomain
ao URL do serviço de declaração de consumidor (ACS) SAML.Confira se
continue_uri
está na lista de domínios autorizados.Implante novamente 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: alternar para signInWithPopup()
Use signInWithPopup()
em vez de
signInWithRedirect()
. O
restante do código do app continua o mesmo, mas a recuperação do objeto
UserCredential é diferente.
Web
// Before
// ==============
signInWithRedirect(auth, new GoogleAuthProvider());
// After the page redirects back
const userCred = await getRedirectResult(auth);
// After
// ==============
const userCred = await signInWithPopup(auth, new GoogleAuthProvider());
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 é o ideal para usuários. Às vezes, os pop-ups são bloqueados pelo dispositivo ou plataforma, e o fluxo é menos estável para os usuários de dispositivos móveis. Se o uso de pop-ups for um problema para o app, aplique outra opção.
Opção 3: solicitações de autenticação de proxy para firebaseapp.com
O fluxo de signInWithRedirect
começa redirecionando o domínio do app para o
domínio especificado no parâmetro authDomain
, na configuração do Firebase
("authDomain
hospeda o código auxiliar de login
que redireciona para o provedor de identidade, que, se não houver nenhum problema, redireciona
para o domínio do app.
Quando o fluxo de autenticação retorna ao domínio do app, obtém-se acesso ao armazenamento do navegador do domínio auxiliar de login. Essa opção e a seguinte (para auto-hospedar o código) mitigam o acesso ao armazenamento de origem cruzada, que, de outra forma, é bloqueado pelos navegadores.
Configure um proxy reverso no servidor do app para que as solicitações GET/POST para
https://<app domain>/__/auth/
sejam encaminhadas parahttps://<project>.firebaseapp.com/__/auth/
. Confirme se o encaminhamento é explícito para o navegador (isso não pode ser feito por meio de um redirecionamento 302).Se você usa o nginx para exibir seu domínio personalizado, a configuração de proxy reverso será como o exemplo abaixo:
# reverse proxy for signin-helpers for popup/redirect sign in. location /__/auth { proxy_pass https://<project>.firebaseapp.com; }
Siga as etapas da Opção 1 para atualizar o
redirect_uri
, o URL do ACS e oauthDomain
autorizados. Depois de implantar novamente o app, não haverá mais o acesso ao armazenamento de origem cruzada.
Opção 4: auto-hospedar o código auxiliar de login no domínio
Outra forma de eliminar o acesso ao armazenamento de origem cruzada é auto-hospedar o código auxiliar de login do Firebase. No entanto, essa abordagem não funciona para o login da Apple ou SAML. Use essa mitigação apenas se a configuração de proxy reverso na opção 3 for inviável.
A hospedagem do código auxiliar divide-se nas etapas abaixo:
Faça o download dos arquivos para hospedar do 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
Hospede os arquivos acima no domínio do app. Verifique se o servidor da Web pode responder a
https://<app domain>/__/auth/<filename>
ehttps://<app domain>/__/firebase/init.json
.Confira um exemplo de implementação do servidor que faz o download e hospeda os arquivos. Recomendamos que você faça o download e a sincronização dos arquivos periodicamente para garantir que as correções de bugs e os recursos mais recentes sejam usados.
Siga as etapas da Opção 1 para atualizar o
redirect_uri
autorizado eauthDomain
. Depois de implantar novamente o app, não haverá mais o acesso ao armazenamento de origem cruzada.
Opção 5: gerenciar o login do provedor de maneira independente
O SDK do Firebase Authentication oferece
signInWithPopup()
e
signInWithRedirect()
como
métodos práticos para encapsular a lógica complexa e evitar a necessidade de envolver
outro SDK. Você pode evitar a necessidade do uso desses métodos fazendo login de maneira
independente no seu provedor e, em seguida, usando signInWithCredential()
para
trocar as credenciais do provedor por uma credencial do Firebase Authentication.
Você pode usar, por exemplo, o
SDK do Login do Google,
o exemplo de código
para receber uma credencial da Conta do Google e, em seguida, instanciar uma nova credencial do Google
executando o seguinte código:
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);
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 app vai funcionar
da mesma forma que antes.
Neste link, você encontra instruções sobre como receber uma credencial da Apple.