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
Use o Swift Package Manager para instalar e gerenciar as dependências do Firebase.
- No Xcode, com seu projeto do app aberto, navegue até File > Add Packages.
- Quando solicitado, adicione o repositório do SDK do Firebase para as plataformas Apple:
- Escolha a biblioteca do Firebase Authentication.
- Quando terminar, o Xcode começará a resolução e fará o download das dependências em segundo plano automaticamente.
https://github.com/firebase/firebase-ios-sdk
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. Ative esse método para poder usar o login por link de e-mail.
- 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 ao usuário uma interface que
solicite que ele forneça seu endereço de e-mail e, em seguida, chame
sendSignInLink
para solicitar que o Firebase
envie o link de autenticação para o e-mail do usuário.
Crie o objeto
ActionCodeSettings
, que fornece ao Firebase instruções sobre como criar o link de e-mail. Defina os seguintes campos:- URL: o link direto a ser incorporado e qualquer estado adicional a ser transmitido junto. É 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).
- iOSBundleID e androidPackageName: os apps a serem usados quando o usuário abrir o link para login em um dispositivo Android ou Apple. Saiba mais sobre como configurar o Firebase Dynamic Links para abrir links de ação por e-mail via apps para dispositivos móveis.
- handleCodeInApp: definido como true. É 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 para dispositivos móveis especificado (por exemplo,
example.page.link
). Caso contrário, o primeiro domínio será selecionado automaticamente.
Swift
let actionCodeSettings = ActionCodeSettings() actionCodeSettings.url = URL(string: "https://www.example.com") // The sign-in operation has to always be completed in the app. actionCodeSettings.handleCodeInApp = true actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!) actionCodeSettings.setAndroidPackageName("com.example.android", installIfNotAvailable: false, minimumVersion: "12")
Objective-C
FIRActionCodeSettings *actionCodeSettings = [[FIRActionCodeSettings alloc] init]; [actionCodeSettings setURL:[NSURL URLWithString:@"https://www.example.com"]]; // The sign-in operation has to always be completed in the app. actionCodeSettings.handleCodeInApp = YES; [actionCodeSettings setIOSBundleID:[[NSBundle mainBundle] bundleIdentifier]]; [actionCodeSettings setAndroidPackageName:@"com.example.android" installIfNotAvailable:NO minimumVersion:@"12"];
Para saber mais sobre o ActionCodeSettings, consulte a seção Como transmitir o estado nas ações de e-mail.
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.
Swift
Auth.auth().sendSignInLink(toEmail: email, actionCodeSettings: actionCodeSettings) { error in // ... if let error = error { self.showMessagePrompt(error.localizedDescription) return } // The link was successfully sent. Inform the user. // Save the email locally so you don't need to ask the user for it again // if they open the link on the same device. UserDefaults.standard.set(email, forKey: "Email") self.showMessagePrompt("Check your email for link") // ... }
Objective-C
[[FIRAuth auth] sendSignInLinkToEmail:email actionCodeSettings:actionCodeSettings completion:^(NSError *_Nullable error) { // ... if (error) { [self showMessagePrompt:error.localizedDescription]; return; } // The link was successfully sent. Inform the user. // Save the email locally so you don't need to ask the user for it again // if they open the link on the same device. [NSUserDefaults.standardUserDefaults setObject:email forKey:@"Email"]; [self showMessagePrompt:@"Check your email for link"]; // ... }];
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 de e-mail precisa ser o mesmo 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. Depois, utilize o endereço para concluir o fluxo.
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 não verificada faça login novamente com ela.
Como concluir o login em um app para dispositivos móveis da Apple
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.
Como configurar o Firebase Dynamic Links
O Firebase Auth usa o Firebase Dynamic Links ao enviar um link que deve ser aberto em um aplicativo para dispositivos móveis. Para usar esse recurso, o Dynamic Links precisa ser configurado no Console do Firebase.
Ative o Firebase Dynamic Links:
- No Console do Firebase, abra a seção Dynamic Links.
-
Caso ainda não tenha aceitado os termos do Dynamic Links e criado um domínio do Dynamic Links, faça isso agora.
Anote o domínio do Dynamic Links se você já tiver criado um. Um domínio do Dynamic Links geralmente se parece com este exemplo:
example.page.link
Você vai precisar desse valor ao configurar o app Android ou Apple para interceptar o link recebido.
Configurar aplicativos da Apple:
- Se você planeja processar esses links no seu aplicativo, o ID do pacote precisa ser especificado nas configurações do projeto no Console do Firebase. Além disso, os IDs da App Store e da equipe de desenvolvedores da Apple também precisam ser especificados.
- Você também precisará configurar o domínio do gerenciador de ações de e-mail como um
domínio associado nos recursos do seu aplicativo. Por padrão, o gerenciador de ações de e-mail é hospedado em um domínio como o exemplo a seguir:
APP_ID.firebaseapp.com
- Se você pretende distribuir seu aplicativo para a versão 8 e anteriores do iOS, será necessário configurar seu ID do pacote como um esquema personalizado para URLs recebidos.
- Para mais informações, consulte Como receber as instruções do Dynamic Links na plataforma da Apple.
Verificar o link e fazer login
Depois de receber o link conforme descrito acima, verifique se ele é destinado à autenticação por e-mail e conclua o login.
Swift
if Auth.auth().isSignIn(withEmailLink: link) { Auth.auth().signIn(withEmail: email, link: self.link) { user, error in // ... } }
Objective-C
if ([[FIRAuth auth] isSignInWithEmailLink:link]) { [[FIRAuth auth] signInWithEmail:email link:link completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { // ... }]; }
Para saber mais sobre como processar o login com o link por e-mail em um app Android, consulte este guia.
Para saber mais sobre como processar o login com o link por e-mail em um aplicativo da Web, consulte este guia.
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:
Swift
let credential = EmailAuthCredential.credential(withEmail:email link:link) Auth.auth().currentUser?.link(with: credential) { authData, error in if (error) { // And error occurred during linking. return } // The provider was successfully linked. // The phone user can now sign in with their phone number or email. }
Objective-C
FIRAuthCredential *credential = [FIREmailAuthProvider credentialWithEmail:email link:link]; [FIRAuth auth].currentUser linkWithCredential:credential completion:^(FIRAuthDataResult *_Nullable result, NSError *_Nullable error) { if (error) { // And error occurred during linking. return; } // The provider was successfully linked. // The phone user can now sign in with their phone number or email. }];
Também é possível usá-lo para reautenticar um usuário de link por e-mail antes de executar uma operação confidencial.
Swift
let credential = EmailAuthProvider.credential(withEmail:email link:link) Auth.auth().currentUser?.reauthenticate(with: credential) { authData, error in if (error) { // And error occurred during re-authentication. return } // The user was successfully re-authenticated. }
Objective-C
FIRAuthCredential *credential = [FIREmailAuthCredential credentialWithEmail:email link:link]; [FIRAuth auth].currentUser reauthenticateWithCredential:credential completion:^(FIRAuthDataResult *_Nullable result, NSError *_Nullable error) { if (error) { // And error occurred during re-authentication return; } // The user was successfully re-authenticated. }];
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 do link por e-mail
Se você aceita logins por senhas e links de e-mail,
diferencie o método de login de uma senha/link de usuário com
fetchSignInMethodsForEmail
. Isso é útil nos fluxos que priorizam identificadores, em que o usuário é solicitado a fornecer o e-mail e precisa escolher o método de login:
Swift
// After asking the user for their email. Auth.auth().fetchSignInMethods(forEmail: email) { signInMethods, error in // This returns the same array as fetchProviders(forEmail:completion:) but for email // provider identified by 'password' string, signInMethods would contain 2 // different strings: // 'emailLink' if the user previously signed in with an email/link // 'password' if the user has a password. // A user could have both. if (error) { // Handle error case. } if (!signInMethods.contains(EmailPasswordAuthSignInMethod)) { // User can sign in with email/password. } if (!signInMethods.contains(EmailLinkAuthSignInMethod)) { // User can sign in with email/link. } }
Objective-C
// After asking the user for their email. [FIRAuth auth] fetchSignInMethodsForEmail:email completion:^(NSArray*_Nullable signInMethods, NSError *_Nullable error) { // This returns the same array as fetchProvidersForEmail but for email // provider identified by 'password' string, signInMethods would contain 2 // different strings: // 'emailLink' if the user previously signed in with an email/link // 'password' if the user has a password. // A user could have both. if (error) { // Handle error case. } if (![signInMethods containsObject:FIREmailPasswordAuthSignInMethod]) { // User can sign in with email/password. } if (![signInMethods containsObject:FIREmailLinkAuthSignInMethod]) { // User can sign in with email/link. } }];
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 faz login pela primeira vez, uma nova conta de usuário é criada e vinculada às credenciais, que podem ser o número do telefone, o nome de usuário e a senha ou as informações do provedor de autenticação. Essa nova conta é armazenada como parte do 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 utilizado.
-
É possível receber as informações básicas de perfil do usuário do objeto
User
nos seus apps. Consulte Gerenciar usuários. Nas Regras de segurança do Firebase Realtime Database e do Cloud Storage, é possível acessar na variável
auth
o ID exclusivo do usuário que fez login e usar esse ID para controlar quais dados uma pessoa 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:
.
Swift
let firebaseAuth = Auth.auth() do { try firebaseAuth.signOut() } catch let signOutError as NSError { print("Error signing out: %@", signOutError) }
Objective-C
NSError *signOutError; BOOL status = [[FIRAuth auth] signOut:&signOutError]; if (!status) { NSLog(@"Error signing out: %@", signOutError); return; }
Adicione também o código de tratamento de erros para todo o intervalo de erros de autenticação. Consulte Tratamento de erros.