Autenticar com o Firebase usando o link por e-mail em plataformas Apple

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.

  1. No Xcode, com seu projeto do app aberto, navegue até File > Add Packages.
  2. Quando solicitado, adicione o repositório do SDK do Firebase para as plataformas Apple:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Escolha a biblioteca Firebase Authentication.
  5. Adicione a sinalização -ObjC à seção Outras sinalizações do vinculador das configurações de compilação do destino.
  6. Quando terminar, o Xcode começará a resolver e fazer o download das dependências em segundo plano automaticamente.

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. Ative esse método para poder usar o login por link de e-mail.
  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, 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.

  1. 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 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).
    • iOSBundleID e androidPackageName: ajudam o Firebase Authentication a determinar se é necessário criar um link somente para Web ou para dispositivos móveis que é aberto em um dispositivo Android ou Apple.
    • handleCodeInApp: definido como verdadeiro. É 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.
    • linkDomain: quando domínios de link personalizados do Hosting são definidos para um projeto, especifique qual deles usar quando o link for aberto por um app para dispositivos móveis especificado. Caso contrário, o domínio padrão será selecionado automaticamente (por exemplo, PROJECT_ID.firebaseapp.com).
    • dynamicLinkDomain: descontinuado. Não especifique esse parâmetro.

    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 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 Hosting 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. Confira a seção sobre links universais e domínios associados no iOS para obter mais detalhes sobre como fazer isso.

Configurar o Firebase Hosting

O Firebase Authentication usa domínios do Firebase Hosting ao criar e enviar um link que deve ser aberto em um aplicativo para dispositivos móveis. Um domínio padrão do Firebase Hosting já foi configurado para você.

  1. Configure os domínios do Firebase Hosting:

    No console do Firebase, abra a seção Hospedagem.

    • Se você quiser usar o domínio padrão para o link de e-mail que é aberto em aplicativos para dispositivos móveis, acesse o site padrão e anote o domínio padrão do Hosting. Um domínio padrão do Hosting geralmente tem esta aparência: PROJECT_ID.firebaseapp.com.

      Você vai precisar desse valor ao configurar o seu app para interceptar o link recebido.

    • Se você quiser usar um domínio personalizado para o link de e-mail, registre um com o Firebase Hosting e use-o para o domínio do link.

  2. Configurar aplicativos da Apple:

    Você vai precisar configurar o domínio escolhido como um domínio associado para links de apps. Para configurar o direito de acesso no app, abra a guia Signing & Capabilities do destino no Xcode e adicione os domínios do Firebase Hosting da etapa anterior ao recurso "Domínios associados". Se você usar o domínio padrão do Firebase Hosting, ele será applinks:PROJECT_ID.firebaseapp.com.

    Consulte Supporting associated domains no site de documentação da Apple para mais informações.

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.

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.

Antes do Firebase Authentication iOS SDK v11.8.0, o recurso de login com link de e-mail dependia do Firebase Dynamic Links para abrir links de login no app correto. Esses links de verificação foram descontinuados, porque o Firebase Dynamic Links será desativado em 25 de agosto de 2025.

Se o app usa os links do estilo antigo, migre o app para o novo sistema baseado no Firebase Hosting.

Se você criou o projeto em 15 de setembro de 2023 ou depois, a proteção contra enumeração de e-mails está ativada por padrão. Esse recurso aumenta a segurança das contas de usuário do projeto, mas desativa o método fetchSignInMethodsForEmail(), que anteriormente recomendamos para implementar fluxos que priorizam identificadores.

Embora você possa desativar a proteção contra enumeração de e-mails para o seu projeto, nós não recomendamos fazer isso.

Para saber mais, consulte Ativar ou desativar a proteção contra enumeração de e-mails.

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 Firebase Realtime Database e Cloud Storage, você pode acessar o ID exclusivo do usuário conectado pela variável auth e usar essas informações 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:.

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.