Use o Firebase Authentication para fazer o login de um usuário por meio de um link enviado a ele por e-mail. Nesse processo, o endereço de e-mail do usuário também é verificado.
O login por e-mail tem inúmeros benefícios:
- Inscrição e login simplificados.
- Menos chances de reutilizar senhas entre os aplicativos, o que pode diminuir a segurança até mesmo das senhas mais fortes.
- Capacidade de autenticar o usuário e verificar se ele é o legítimo proprietário do endereço de e-mail.
- O usuário só precisa de uma conta de e-mail acessível para fazer login. Não são necessários números de telefone nem contas em redes sociais.
- O usuário faz login com segurança sem precisar fornecer ou lembrar de uma senha. Em dispositivos móveis, isso é bem importante porque facilita a vida do usuário.
- O usuário que já tiver feito login com um identificador de e-mail (senha ou federado) poderá se conectar depois apenas com o e-mail. Por exemplo, se ele se esquecer da senha, ainda será possível fazer login sem precisar redefini-la.
Antes de começar
Siga as etapas no guia Primeiros passos, caso ainda não tenha feito isso.
Ativar o login por link de e-mail no projeto do Firebase.
Para que os usuários façam login usando um link enviado por e-mail, primeiro ative o provedor de e-mail e o método de login por link no projeto do Firebase:
- No Console do Firebase, abra a seção Auth.
- Na guia Método de login, ative o provedor de E-mail/senha. Lembre-se de que você precisa ativar esse método para poder usar o login por link.
- Na mesma seção, ative o método Link do e-mail (login sem senha).
- Clique em Salvar.
Enviar um link de autenticação ao endereço de e-mail do usuário
Para iniciar o fluxo de autenticação, apresente uma interface que solicite que o usuário forneça seu endereço de e-mail e, em seguida, chame sendSignInLinkToEmail()
para solicitar que o Firebase envie o link de autenticação para o e-mail do usuário.
Crie o objeto ActionCodeSettings, que fornece instruções ao Firebase para gerar o link do e-mail. Defina os seguintes campos:
url
: o link direto para incorporar e qualquer estado adicional a ser transmitido. É preciso que o domínio do link esteja na lista de permissões de domínios autorizados do Console do Firebase, encontrada na guia Método de login (Autenticação -> Método de login). O link redirecionará o usuário para esse URL se o aplicativo não estiver instalado e não for possível instalar ele no dispositivo.androidPackageName
eIOSBundleId
: os aplicativos que devem ser usados quando o link para login é aberto em um dispositivo Android ou iOS. Saiba mais sobre como configurar o Firebase Dynamic Links para abrir links de ação por e-mail via apps para dispositivos móveis.Defina
handleCodeInApp
comotrue
. É necessário sempre concluir o processo de login no app, ao contrário de outras ações fora de banda, como redefinição de senha e verificação de e-mail. Isso acontece porque o usuário precisa estar conectado e com o estado Auth mantido no app ao final do fluxo.dynamicLinkDomain
: quando vários domínios de link dinâmico personalizados forem definidos para um projeto, especifique qual deles usar quando o link for aberto por um app específico para dispositivos móveis (por exemplo,example.page.link
). Caso contrário, o primeiro domínio será selecionado automaticamente.
var acs = ActionCodeSettings( // URL you want to redirect back to. The domain (www.example.com) for this // URL must be whitelisted in the Firebase Console. url: 'https://www.example.com/finishSignUp?cartId=1234', // This must be true handleCodeInApp: true, iOSBundleId: 'com.example.ios', androidPackageName: 'com.example.android', // installIfNotAvailable androidInstallApp: true, // minimumVersion androidMinimumVersion: '12');
Solicite o e-mail ao usuário.
Envie o link de autenticação a esse endereço e salve o e-mail caso o usuário conclua o login no mesmo dispositivo.
var emailAuth = 'someemail@domain.com'; FirebaseAuth.instance.sendSignInLinkToEmail( email: emailAuth, actionCodeSettings: acs) .catchError((onError) => print('Error sending email verification $onError')) .then((value) => print('Successfully sent email verification')); });
Concluir o login com o link do e-mail
Preocupações com segurança
No Firebase Auth, o usuário precisa fornecer o endereço de e-mail ao concluir o fluxo de login. Isso evita que o link seja usado para fazer o login de um usuário indesejado ou em um dispositivo não intencional. Para realizar o login, esse endereço precisa ser igual ao e-mail que recebeu o link.
É possível simplificar o fluxo dos usuários que abrem o link no mesmo dispositivo usado para solicitá-lo. Basta armazenar o endereço deles localmente quando enviar o e-mail de login. Por exemplo, você pode usar o SharedPreferences. Depois, utilize o endereço para concluir o fluxo. Não transmita o e-mail do usuário nos parâmetros de URL de redirecionamento e o reutilize, já que isso pode ativar injeções de sessão.
Após a conclusão do login, qualquer mecanismo anterior de login não verificado será removido do usuário, e todas as sessões atuais serão invalidadas. Por exemplo, se alguém tiver criado uma conta não verificada com a mesma senha e e-mail, a senha do usuário será removida. Isso impede que a pessoa que reivindicou a propriedade e criou essa conta faça login novamente com o e-mail e senha não confirmados.
Além disso, não deixe de usar um URL HTTPS na produção para impedir que o link possa ser interceptado por servidores intermediários.
Verificar o link por e-mail e fazer login
O Firebase Authentication usa o Firebase Dynamic Links para enviar o link por e-mail a um dispositivo móvel. No aplicativo para dispositivos móveis, ele precisa estar configurado para detectar o link de entrada, analisar o link direto e então concluir o login.
Configure seu app para receber links dinâmicos no Flutter no guia.
No gerenciador de links, verifique se o link é destinado à autenticação por e-mail e, em caso afirmativo, conclua o processo de login.
// Confirm the link is a sign-in with email link. if (FirebaseAuth.instance.isSignInWithEmailLink(emailLink)) { try { // The client SDK will parse the code from the link for you. final userCredential = await FirebaseAuth.instance .signInWithEmailLink(email: emailAuth, emailLink: emailLink); // You can access the new user via userCredential.user. final emailAddress = userCredential.user?.email; print('Successfully signed in with email link!'); } catch (error) { print('Error signing in with email link.'); } }
Como vincular/reautenticar com link por e-mail
Também é possível vincular este método de autenticação a um usuário atual. Por exemplo, um usuário já autenticado com outro provedor, como número de telefone, pode incluir este método de login na conta dele.
A diferença está na segunda metade da operação:
final authCredential = EmailAuthProvider
.credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
await FirebaseAuth.instance.currentUser
?.linkWithCredential(authCredential);
} catch (error) {
print("Error linking emailLink credential.");
}
Também é possível usá-lo para reautenticar um usuário de link por e-mail antes de executar uma operação confidencial.
final authCredential = EmailAuthProvider
.credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
await FirebaseAuth.instance.currentUser
?.reauthenticateWithCredential(authCredential);
} catch (error) {
print("Error reauthenticating credential.");
}
No entanto, este fluxo pode não ser concluído, já que ele pode terminar em um dispositivo diferente do que o usado para fazer login. Nesse caso, é possível exibir um erro ao usuário para obrigá-lo a abrir o link no mesmo dispositivo. Você pode transmitir um estado no link para fornecer informações sobre o tipo de operação e o UID do usuário.
Como diferenciar e-mail/senha de link por e-mail
Caso você tenha suporte para login com senha e login com base em link por e-mail, para diferenciar o método de login de um usuário de senha/link, use fetchSignInMethodsForEmail
. Isso é útil nos fluxos que priorizam identificadores, em que
o usuário precisa indicar o e-mail e, em seguida, escolher o
método de login:
try {
final signInMethods =
await FirebaseAuth.instance.fetchSignInMethodsForEmail(emailAuth);
final userExists = signInMethods.isNotEmpty;
final canSignInWithLink = signInMethods
.contains(EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD);
final canSignInWithPassword = signInMethods
.contains(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD);
} on FirebaseAuthException catch (exception) {
switch (exception.code) {
case "invalid-email":
print("Not a valid email address.");
break;
default:
print("Unknown error.");
}
}
Conforme descrito acima, e-mail/senha e e-mail/link são considerados os mesmos
EmailAuthProvider
(mesmo PROVIDER_ID
) com diferentes métodos de
login.
Próximas etapas
Depois que um usuário cria uma nova conta, ela é armazenada como parte do seu projeto do Firebase e pode ser usada para identificar um usuário em todos os apps do projeto, seja qual for o método de login usado.
É possível receber as informações básicas de perfil do usuário do objeto
User
nos seus aplicativos. Consulte Gerenciar usuários.
Nas Regras de segurança do Firebase Realtime Database e do Cloud Storage, é possível
receber o ID do usuário único conectado da variável auth
e usar esse ID para controlar quais dados um usuário pode acessar.
Os usuários podem fazer login no app usando vários provedores de autenticação. Basta vincular as credenciais desses provedores a uma conta de usuário.
Para desconectar um usuário, chame signOut()
:
await FirebaseAuth.instance.signOut();