Ir para o console

Autenticar com o Firebase usando link por e-mail no iOS

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úmeras vantagens:

  • Inscrição e login menos complicados.
  • Menos chances de reutilizar senhas entre os aplicativos, o que poderia 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úmero de telefone ou conta em redes sociais.
  • O usuário faz login com segurança sem precisar fornecer ou lembrar uma senha, ações que podem ser incômodas em dispositivos móveis.
  • O usuário que já tiver feito login com um identificador de e-mail (senha ou federado) poderá se conectar posteriormente 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

  1. Adicione o Firebase ao projeto do iOS. Inclua os pods a seguir no Podfile:
    pod 'Firebase/Auth'
  2. Se você ainda não conectou o app ao projeto do Firebase, faça isso no Console 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:

  1. No Console do Firebase, abra a seção Auth.
  2. 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.
  3. Na mesma seção, ative o método Link do e-mail (login sem senha).
  4. Clique em Salvar.

Para iniciar o fluxo de autenticação, forneça ao usuário uma interface que solicite o endereço de e-mail dele. Depois, chame sendSignInLinkToEmail:actionCodeSettings:completion: para solicitar que o Firebase envie o link de autenticação a esse e-mail.

  1. Crie o objeto ActionCodeSettings, que fornece ao Firebase instruções para gerar o link do e-mail. Configure os campos a seguir:

    • 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 iOS. Saiba mais sobre como configurar o Firebase Dynamic Links para abrir links de ação por e-mail via aplicativos 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 customizados são definidos em um projeto, especifique qual deles usar se o link precisar ser aberto em um determinado app para dispositivos móveis (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.

  2. Solicite o e-mail ao usuário.

  3. 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"];
        // ...
    }];
    

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. 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 existentes 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 ela.

Como concluir o login em um app para dispositivos móveis iOS

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 subjacente e então concluir o login.

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.

  1. Ative o Firebase Dynamic Links:

    1. No Console do Firebase, abra a seção Dynamic Links.
    2. Caso ainda não tenha aceitado os termos do Dynamic Links e criado um domínio do Dynamic Links, faça isso agora.

      Se você já tiver criado um domínio do Dynamic Links, anote-o. Um domínio do Dynamic Links costuma se parecer com este exemplo:

      example.page.link

      Você precisará desse valor ao configurar o app para Android ou iOS para interceptar o link recebido.

  2. Como configurar apps para iOS:

    1. Se você planeja processar esses links do aplicativo para iOS, o código do pacote do iOS precisa ser especificado nas configurações do projeto do Console do Firebase. Além disso, os códigos da App Store e da equipe de desenvolvedores da Apple também precisam ser especificados.
    2. 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
    3. Se você pretende distribuir seu aplicativo para a versão 8 e anteriores do iOS, será necessário configurar o código do seu pacote do iOS como um esquema personalizado para URLs recebidos.
    4. Para ver mais informações, consulte Como receber as instruções do Dynamic Links no iOS.

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 aplicativo para 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.

Também é possível vincular este método de autenticação a um usuário existente. 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.

Caso ambos os logins por senha e por link de e-mail sejam compatíveis, use fetchSignInMethodsForEmail para diferenciar o método de login do usuário. 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 têm o mesmo FIREmailAuthProvider (PROVIDER_ID igual) com diferentes métodos de login.

Próximas etapas

Depois que um usuário faz login pela primeira vez, uma nova conta é 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. Ela pode ser usada para identificar um usuário em todos os apps do projeto, independentemente do método de login usado.

  • Nos apps, é possível acessar as informações básicas de perfil do usuário a partir do objeto FIRUser. Consulte Gerenciar usuários.

  • Nas Regras de segurança do Firebase Realtime Database e do Cloud Storage, é possível usar a variável auth para encontrar o código exclusivo do usuário conectado. Use essa informação para controlar os dados que os usuários podem 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 gerenciamento dos possíveis erros de autenticação. Consulte Solucionar erros.