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 inícios de sessão de redirecionamento em navegadores que bloqueiam cookies de terceiros. Tem de seguir uma das opções indicadas aqui para que signInWithRedirect()
funcione como previsto em ambientes de produção, em todos os navegadores.
Vista geral
Para tornar o fluxo de
signInWithRedirect()
transparente para si e para os seus utilizadores, o SDK JavaScript de autenticação do Firebase usa um iframe de origem cruzada que se liga ao domínio do Firebase Hosting da sua app.
No entanto, este mecanismo não funciona com navegadores que bloqueiam o acesso ao armazenamento de terceiros.
Uma vez que pedir aos utilizadores para desativarem as funcionalidades de partição de armazenamento no navegador é raramente uma opção, deve, em alternativa, aplicar uma das seguintes opções de configuração à sua app, consoante os detalhes do seu exemplo de utilização.
- Se alojar a sua app com o Firebase Hosting num subdomínio de
firebaseapp.com
, não é afetado por este problema e não tem de fazer nada. - Se alojar a sua app com o Firebase Hosting num domínio personalizado ou num subdomínio de
web.app
, use a Opção 1. - Se alojar a sua app com um serviço que não seja o Firebase, use a Opção 2, Opção 3, Opção 4, ou Opção 5.
Opção 1: atualize a configuração do Firebase para usar o seu domínio personalizado como authDomain
Se estiver a alojar a sua app com o Firebase Hosting através de um domínio personalizado, pode configurar o SDK do Firebase para usar o seu domínio personalizado como o authDomain
. Isto garante que a sua app e o iFrame de autenticação usam o mesmo domínio, o que evita o problema de início de sessão. (Se não usar o Firebase Hosting, tem de usar uma opção diferente.) Certifique-se de que configurou o domínio personalizado no mesmo projeto que está a usar para a autenticação.
Para atualizar a configuração do Firebase de modo a usar o seu domínio personalizado como domínio de autenticação, faça o seguinte:
Configure o SDK do Firebase JS para usar o 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 seu fornecedor de OAuth. A forma como o faz depende do fornecedor, mas, em geral, pode seguir a secção "Antes de começar" em qualquer fornecedor para obter instruções exatas (por exemplo, o fornecedor do Facebook). O URI atualizado para autorizar tem o seguinte aspeto:https://<the-domain-that-serves-your-app>/__/auth/handler
. O/__/auth/handler
no final é importante.Da mesma forma, se estiver a usar um fornecedor SAML, adicione o novo
authDomain
ao URL do serviço de consumo de declarações SAML (ACS).Certifique-se de que o seu
continue_uri
está na lista de domínios autorizados.Volte a implementar com o Firebase Hosting, se necessário, para obter o ficheiro de configuração do Firebase mais atualizado alojado em
/__/firebase/init.json
.
Opção 2: mude para signInWithPopup()
Use signInWithPopup()
em vez de
signInWithRedirect()
. O resto do código da sua app permanece igual, mas o objeto UserCredential é obtido de forma diferente.
Versão 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());
Versão 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());
```
O início de sessão através de pop-ups nem sempre é ideal para os utilizadores. Por vezes, os pop-ups são bloqueados pelo dispositivo ou pela plataforma, e o fluxo é menos fluido para os utilizadores de dispositivos móveis. Se a utilização de pop-ups for um problema para a sua app, tem de seguir uma das outras opções.
Opção 3: encaminhe pedidos de autorização para firebaseapp.com
O fluxo signInWithRedirect
começa com um redirecionamento do domínio da sua app para o domínio especificado no parâmetro authDomain
na configuração do Firebase ("authDomain
aloja o código do auxiliar de início de sessão que redireciona para o fornecedor de identidade que, em caso de êxito, redireciona de volta para o domínio da app.
Quando o fluxo de autenticação regressa ao domínio da sua app, é acedido o armazenamento do navegador do domínio do auxiliar de início de sessão. Esta opção e a seguinte (para alojar o código autonomamente) eliminam o acesso ao armazenamento de origem cruzada, que, de outra forma, é bloqueado pelos navegadores.
Configure um proxy inverso no servidor da app para que os pedidos GET/POST para
https://<app domain>/__/auth/
sejam encaminhados parahttps://<project>.firebaseapp.com/__/auth/
. Certifique-se de que este encaminhamento é transparente para o navegador. Não é possível fazê-lo através de um redirecionamento 302.Se estiver a usar o nginx para publicar o seu domínio personalizado, a configuração do proxy inverso tem o seguinte aspeto:
# reverse proxy for signin-helpers for popup/redirect sign in. location /__/auth { proxy_pass https://<project>.firebaseapp.com; }
Siga os passos na Opção 1 para atualizar o
redirect_uri
autorizado, o URL do ACS e o seuauthDomain
. Depois de voltar a implementar a app, o acesso ao armazenamento de origem cruzada deve deixar de ocorrer.
Opção 4: aloje o código do auxiliar de início de sessão no seu domínio
Outra forma de eliminar o acesso ao armazenamento de origem cruzada é alojar autonomamente o código auxiliar de início de sessão do Firebase. No entanto, esta abordagem não funciona para o início de sessão da Apple nem para o SAML. Use esta opção apenas se a configuração do proxy inverso na opção 3 for inviável.
A alojamento do código auxiliar tem os seguintes passos:
Transfira os ficheiros para alojamento a partir da localização
<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
Aloje os ficheiros acima no domínio da sua app. Certifique-se de que o seu servidor Web consegue responder a
https://<app domain>/__/auth/<filename>
ehttps://<app domain>/__/firebase/init.json
.Segue-se uma implementação de servidor de exemplo que transfere e aloja os ficheiros. Recomendamos que transfira e sincronize os ficheiros periodicamente para garantir que as correções de erros e as funcionalidades mais recentes são aplicadas.
Siga os passos na Opção 1 para atualizar o
redirect_uri
autorizado e o seuauthDomain
. Depois de voltar a implementar a app, o acesso ao armazenamento de origem cruzada deve deixar de ocorrer.
Opção 5: processar o início de sessão do fornecedor de forma independente
O SDK Firebase Authentication fornece
signInWithPopup()
e
signInWithRedirect()
como métodos práticos para encapsular lógica complicada e evitar a necessidade de envolver
outro SDK. Pode evitar usar qualquer um dos métodos iniciando sessão de forma independente no seu fornecedor e, em seguida, usando signInWithCredential()
para trocar as credenciais do fornecedor por uma credencial da Firebase Authentication.
Por exemplo, pode usar o
SDK de início de sessão Google,
código de amostra
para obter uma credencial de conta Google e, em seguida, instanciar uma nova credencial Google,
executando o seguinte código:
Versão 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);
Versão 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);
Depois de chamar signInWithCredential()
, o resto da app funciona da mesma forma que antes.
Pode encontrar instruções para obter uma credencial da Apple aqui.