Ir para o console

Autenticar com o Firebase no iOS usando um número de telefone

Use o Firebase Authentication para fazer o login de um usuário. Basta enviar uma mensagem SMS para o telefone do usuário. O usuário faz login com um código de uso único contido na mensagem SMS.

A maneira mais fácil de adicionar o login com número de telefone ao app é usar a FirebaseUI. Ela inclui um widget drop-in que implementa fluxos para logins com número de telefone, bem como logins por senha ou federados. Este documento descreve como implementar um fluxo de login com número de telefone por meio do SDK do Firebase.

Antes de começar

  1. Adicione o Firebase ao seu projeto do iOS.
  2. Inclua os seguintes pods no seu Podfile:
    pod 'Firebase/Auth'
  3. Caso você ainda não tenha conectado o app ao seu projeto do Firebase, faça isso no Firebase console.

Preocupações com segurança

A autenticação usando apenas um número de telefone é conveniente, porém menos segura do que os outros métodos disponíveis, já que um número de telefone pode ser facilmente transferido entre usuários. Além disso, em dispositivos com vários perfis de usuário, qualquer um que receba mensagens SMS pode fazer login em uma conta usando o número de telefone do dispositivo.

Caso use o login por número de telefone no seu app, você precisa oferecê-lo junto com métodos de login mais seguros e informar aos usuários as implicações de segurança do uso desse tipo de login.

Ativar o login com número de telefone para o projeto do Firebase

Para fazer login de usuários por SMS, ative primeiro o método de login com número de telefone para o projeto do Firebase:

  1. No Console do Firebase, abra a seção Autenticação.
  2. Na página Método de login, ative o método de login por Número de telefone.

A cota de solicitação de login com número de telefone do Firebase é alta o suficiente para evitar que a maioria dos apps seja afetada. No entanto, se for necessário fazer login de um grande volume de usuários com autenticação por telefone, atualize o plano de preços. Consulte a página de preços.

Ativar a verificação do aplicativo

Para usar a autenticação por número de telefone, o Firebase precisa verificar se as solicitações de login do número de telefone estão vindo do seu aplicativo. O Firebase Authentication faz isso de duas maneiras:

  • Notificações de APNs silenciosas: quando você faz login de um usuário com o número de telefone pela primeira vez em um dispositivo, o Firebase Authentication envia um token para o dispositivo usando uma notificação push silenciosa. Se o aplicativo recebe com êxito a notificação do Firebase, o login com o número de telefone pode prosseguir.

    Para o iOS 8.0 e versões mais recentes, as notificações silenciosas não exigem o consentimento explícito do usuário e, portanto, não são afetadas por um usuário que escolha não receber notificações APN no app. Assim, o app não precisa solicitar a permissão do usuário para receber notificações push ao implementar a autenticação com o número de telefone do Firebase.

  • Verificação reCAPTCHA: no caso em que o envio ou recebimento de uma notificação de envio silencioso não é possível, como quando o usuário desativou a atualização em segundo plano para seu app ou ao testar seu app em um simulador de iOS, o Firebase Authentication usa a verificação reCAPTCHA para completar o fluxo de login com número de telefone. O desafio do reCAPTCHA pode ser concluído sem que o usuário tenha que resolver nada.

Quando as notificações push silenciosas são configuradas corretamente, apenas uma porcentagem muito pequena de usuários terá experiências com o fluxo reCAPTCHA. No entanto, você precisa garantir que o login do número de telefone funcione corretamente, independentemente de as notificações push silenciosas estarem ou não disponíveis.

Receber notificações silenciosas

Para ativar notificações de APNs para uso com o Firebase Authentication:

  1. No Xcode, ative notificações push para seu projeto.
  2. Faça upload da chave de autenticação de APNs para o Firebase. Se você ainda não tem uma chave de autenticação de APNs, consulte Configurar APNs com o FCM.

    1. No seu projeto do Firebase console, selecione o ícone de engrenagem, Configurações do projeto e a guia Cloud Messaging.

    2. Acesse a Configuração do app para iOS. Em Chave de autenticação de APNs, clique no botão Upload.

    3. Navegue até o local onde você salvou a chave, selecione-a e clique em Abrir. Adicione o código da chave, disponível em Certificates, Identifiers & Profiles no Apple Developer Member Center (em inglês) e clique em Upload.

    Você pode fazer upload do certificado se já tiver um certificado APN.

Configurar a verificação reCAPTCHA

Para ativar o SDK do Firebase para usar a verificação reCAPTCHA:

  1. Adicione esquemas de URL personalizado ao seu projeto do Xcode:
    1. Abra a configuração do seu projeto: clique duas vezes no nome dele na visualização em árvore à esquerda. Selecione seu app na seção DESTINOS. Em seguida, selecione a guia Informações e expanda a seção Tipos de URL.
    2. Clique no botão + e adicione um esquema de URL para o código do cliente reverso. Para encontrar esse valor, abra o arquivo de configuração GoogleService-Info.plist e procure a chave REVERSED_CLIENT_ID. Copie e cole o valor da chave na caixa Esquemas de URL na página de configuração. Deixe os outros campos em branco.

      Quando concluída, a configuração será semelhante à mostrada a seguir, mas com os valores específicos do seu app:

  2. Opcional: se quiser personalizar a forma como o app apresenta o SFSafariViewController ou o UIWebView ao exibir o reCAPTCHA para o usuário, crie uma classe personalizada que esteja em conformidade com o protocolo FIRAuthUIDelegate e transmita-a para verifyPhoneNumber:UIDelegate:completion:.

Enviar um código de verificação ao smartphone do usuário

Para dar início ao login com número de telefone, apresente ao usuário uma interface que solicite o número dele e, em seguida, chame verifyPhoneNumber:UIDelegate:completion: para pedir que o Firebase envie um código de autenticação ao smartphone do usuário por SMS:

  1. Solicite o número de telefone do usuário.

    Os requisitos legais variam, mas como prática recomendada e para definir as expectativas dos usuários, informe a eles que, se fizerem login com o número de telefone, poderão receber uma mensagem SMS para verificação. Além disso, poderão ser cobrados por esse serviço.

  2. Chame verifyPhoneNumber:UIDelegate:completion:, passando a ele o número de telefone do usuário.

    Swift

    PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) { (verificationID, error) in
      if let error = error {
        self.showMessagePrompt(error.localizedDescription)
        return
      }
      // Sign in using the verificationID and the code sent to the user
      // ...
    }

    Objective-C

    [[FIRPhoneAuthProvider provider] verifyPhoneNumber:userInput
                                            UIDelegate:nil
                                            completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
      if (error) {
        [self showMessagePrompt:error.localizedDescription];
        return;
      }
      // Sign in using the verificationID and the code sent to the user
      // ...
    }];

    Quando você chama verifyPhoneNumber:UIDelegate:completion:, o Firebase envia uma notificação push silenciosa para o app ou emite um desafio reCAPTCHA para o usuário. Depois que seu app recebe a notificação ou o usuário completa o desafio reCAPTCHA, o Firebase envia uma mensagem SMS com um código de autenticação ao número de telefone especificado e transmite uma identificação da verificação para a função de conclusão. Você precisará do código de verificação e da identificação da verificação para fazer o login do usuário.

    A mensagem SMS enviada pelo Firebase também pode ser localizada ao especificar a linguagem de autenticação por meio da propriedade languageCode na sua instância Auth.

    Swift

     // Change language code to french.
     Auth.auth().languageCode = "fr";
    

    Objective-C

     // Change language code to french.
     [FIRAuth auth].languageCode = @"fr";
    
  3. Salve a identificação da verificação e restaure-a depois que o app for carregado. Ao fazer isso, você tem a garantia de ter uma identificação da verificação válida caso o app seja encerrado antes que o usuário conclua o fluxo de login (por exemplo, ao alternar para o app de SMS).

    Persista com a identificação da verificação da maneira que quiser. Uma maneira simples é salvar a identificação da verificação com o objeto NSUserDefaults:

    Swift

    UserDefaults.standard.set(verificationID, forKey: "authVerificationID")
    

    Objective-C

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:verificationID forKey:@"authVerificationID"];
    

    Em seguida, você poderá restaurar o valor salvo:

    Swift

    let verificationID = UserDefaults.standard.string(forKey: "authVerificationID")
    

    Objective-C

    NSString *verificationID = [defaults stringForKey:@"authVerificationID"];
    

Se a chamada para verifyPhoneNumber:UIDelegate:completion: tiver sucesso, você poderá solicitar que o usuário digite o código de verificação quando recebê-lo na mensagem SMS.

Como fazer login do usuário com código de verificação

Depois que o usuário informar o código de verificação da mensagem SMS ao app, faça o login desse usuário. Para isso, crie um objeto FIRPhoneAuthCredential por meio do código e da identificação da verificação e transmita-o para signInWithCredential:completion:

  1. Solicite o código de verificação ao usuário.
  2. Crie um objeto FIRPhoneAuthCredential a partir do código de verificação e da identificação da verificação.

    Swift

    let credential = PhoneAuthProvider.provider().credential(
        withVerificationID: verificationID,
        verificationCode: verificationCode)

    Objective-C

    FIRAuthCredential *credential = [[FIRPhoneAuthProvider provider]
        credentialWithVerificationID:verificationID
                    verificationCode:userInput];
  3. Faça o login do usuário com o objeto FIRPhoneAuthCredential:

    Swift

    Auth.auth().signInAndRetrieveData(with: credential) { (authResult, error) in
      if let error = error {
        // ...
        return
      }
      // User is signed in
      // ...
    }

    Objective-C

    [[FIRAuth auth] signInAndRetrieveDataWithCredential:credential
                                             completion:^(FIRAuthDataResult * _Nullable authResult,
                                                          NSError * _Nullable error) {
      if (error) {
        // ...
        return;
      }
      // User successfully signed in. Get user data from the FIRUser object
      if (authResult == nil) { return; }
      FIRUser *user = authResult.user;
      // ...
    }];

Testar com números de telefone na lista de permissões

Use o Firebase console para adicionar números de telefone à lista de permissões para o desenvolvimento. Essa ação é vantajosa por estes motivos:

  • É feita a autenticação do número de telefone sem consumir sua cota de uso.
  • É feita a autenticação do número de telefone sem enviar mensagem SMS real.
  • São executados testes consecutivos com o mesmo número de telefone, sem que haja limitação. Isso minimiza o risco de rejeição durante o processo de revisão da App store, caso o revisor use o mesmo número de telefone para teste.
  • É feito prontamente o teste em ambientes de desenvolvimento, sem esforço extra como a capacidade de desenvolver um simulador do iOS ou um emulador do Android sem o Google Play Services.
  • É feita a gravação de testes de integração sem que haja bloqueio por verificações de segurança, normalmente aplicadas a números de telefone reais em um ambiente de produção.

Os números de telefone da lista de permissões precisam atender aos seguintes requisitos:

  1. Use números fictícios. Não é permitido, pelo Firebase Authentication, a colocação de números de telefones existentes na lista de permissões. Uma opção é usar números com 555 e prefixos, como números de telefone de teste dos EUA, por exemplo: +1 650-555-3434
  2. Os números de telefone precisam estar formatados corretamente para atender a restrições como o tamanho. Eles ainda passarão pela mesma validação dos números de usuários reais.
  3. Você pode adicionar até dez números de telefone para desenvolvimento.
  4. Use números de telefone/códigos de teste difíceis de adivinhar e altere-os com frequência.

Colocar números de telefone e códigos de verificação na lista de permissões

  1. No Console do Firebase, abra a seção Autenticação.
  2. Na guia Método de login, ative o provedor de telefone, se ainda não o fez.
  3. Abra o menu suspenso Números de telefone para testes.
  4. Informe o número de telefone que você quer testar, por exemplo: +1 650-555-3434.
  5. Informe o código de verificação de seis dígitos para esse número específico, por exemplo: 654321.
  6. Adicione o número. Se precisar, você pode excluir o número de telefone e o código. Basta passar o cursor sobre a linha correspondente e clicar no ícone da lixeira.

Teste manual

É possível começar a usar um número de telefone da lista de permissões diretamente no aplicativo. Dessa maneira, você pode executar testes manuais durante as etapas de desenvolvimento sem problemas de cotas ou limitações. Também é possível testar diretamente, a partir de um simulador do iOS ou emulador do Android, sem a instalação do Google Play Services.

Quando você informa o número de telefone da lista de permissões e envia o código de verificação, não ocorre o envio de um SMS real. Em vez disso, é necessário informar o código de verificação configurado anteriormente para concluir o login.

Quando o login é concluído, é criado um usuário do Firebase com aquele número de telefone. O usuário tem o mesmo comportamento e propriedades de um usuário com um número de telefone real e pode acessar Realtime Database/Cloud Firestore e outros serviços da mesma forma. O token do código gerado durante esse processo tem a mesma assinatura de um usuário com um número de telefone real.

Outra opção é definir um papel de teste por meio de declarações personalizadas nesses usuários para diferenciá-los como usuários falsos, se você quiser restringir ainda mais o acesso.

Teste de integração

Além do teste manual, o Firebase Authentication conta com APIs para ajudar a escrever testes de integração para o teste de autenticação por telefone. Para desativar a verificação de aplicativos, essas APIs desativam o requisito reCAPTCHA nas notificações push na Web e silenciosas no iOS. Isso possibilita testes de automação nesses fluxos e facilita a implementação. Além disso, fica mais fácil testar os fluxos de verificação instantânea no Android.

No iOS, a configuração appVerificationDisabledForTesting deve ser definida como TRUE antes que verifyPhoneNumber seja chamado. O processamento não exige tokens de APN nem o envio de notificações push silenciosas em segundo plano, o que facilita o teste em um simulador. Além disso, o fluxo de fallback do reCAPTCHA é desativado.

Observe que, quando a verificação de apps está desativada, o login não é concluído se for usado um número de telefone não listado entre os permitidos. Somente números de telefone permitidos podem ser usados com essa API.

Swift

let phoneNumber = "+16505554567"

// This test verification code is specified for the given test phone number in the developer console.
let testVerificationCode = "123456"

Auth.auth().settings.isAppVerificationDisabledForTesting = TRUE
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate:nil) {
                                                            verificationID, error in
    if (error) {
      // Handles error
      self.handleError(error)
      return
    }
    let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID ?? "",
                                                               verificationCode: testVerificationCode)
    Auth.auth().signInAndRetrieveData(with: credential) { authData, error in
      if (error) {
        // Handles error
        self.handleError(error)
        return
      }
      _user = authData.user
    }];
}];

Objective-C

NSString *phoneNumber = @"+16505554567";

// This test verification code is specified for the given test phone number in the developer console.
NSString *testVerificationCode = @"123456";

[FIRAuth auth].settings.appVerificationDisabledForTesting = YES;
[[FIRPhoneAuthProvider provider] verifyPhoneNumber:phoneNumber
                                        completion:^(NSString *_Nullable verificationID,
                                                     NSError *_Nullable error) {
    if (error) {
      // Handles error
      [self handleError:error];
      return;
    }
    FIRAuthCredential *credential =
        [FIRPhoneAuthProvider credentialWithVerificationID:verificationID
                                          verificationCode:testVerificationCode];
    [FIRAuth auth] signInWithAndRetrieveDataWithCredential:credential
                                                completion:^(FIRUser *_Nullable user,
                                                             NSError *_Nullable error) {
      if (error) {
        // Handles error
        [self handleError:error];
        return;
      }
      _user = user;
    }];
}];

Apêndice: como usar o login com número de telefone sem swizzling

O Firebase Authentication usa o método swizzling para receber automaticamente o token de APNs do app, para manipular as notificações push silenciosas que o Firebase envia para seu app e para interceptar automaticamente o redirecionamento do esquema personalizado da página de verificação do reCAPTCHA durante a verificação.

Se você preferir não usar o swizzling, basta adicionar a sinalização FirebaseAppDelegateProxyEnabled ao arquivo Info.plist do app e defini-la como NO para desativá-lo. Observe que, ao definir essa sinalização como NO, o swizzling também será desativado em outros produtos do Firebase, incluindo o Firebase Cloud Messaging.

Se você desativar swizzling, será necessário passar explicitamente o token do dispositivo de APNs, notificações push e o URL de redirecionamento do esquema personalizado para o Firebase Authentication.

Para receber o token de APNs do dispositivo, implemente o método application:didRegisterForRemoteNotificationsWithDeviceToken: e passe nele o token do dispositivo para o método setAPNSToken:type: do FIRAuth.

Swift

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  // Pass device token to auth
  Auth.auth().setAPNSToken(deviceToken, type: AuthAPNSTokenTypeProd)

  // Further handling of the device token if needed by the app
  // ...
}

Objective-C

- (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  // Pass device token to auth.
  [[FIRAuth auth] setAPNSToken:deviceToken type:FIRAuthAPNSTokenTypeProd];
  // Further handling of the device token if needed by the app.
}

Para processar notificações push, no método application:didReceiveRemoteNotification:fetchCompletionHandler:, verifique se há notificações relacionadas ao Firebase Authentication chamando o método canHandleNotification: do FIRAuth.

Swift

func application(_ application: UIApplication,
    didReceiveRemoteNotification notification: [AnyHashable : Any],
    fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
  if Auth.auth().canHandleNotification(notification) {
    completionHandler(UIBackgroundFetchResultNoData)
    return
  }
  // This notification is not auth related, developer should handle it.
}

Objective-C

- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)notification
          fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  // Pass notification to auth and check if they can handle it.
  if ([[FIRAuth auth] canHandleNotification:notification]) {
    completionHandler(UIBackgroundFetchResultNoData);
    return;
  }
  // This notification is not auth related, developer should handle it.
}

Para processar o URL de redirecionamento do esquema personalizado, implemente o método application:openURL:sourceApplication:annotation: para dispositivos que executam o iOS 8 e versões anteriores, e o método application:openURL:options: para dispositivos que executam o iOS 9 e versões posteriores. Neles, passe o URL para o método canHandleURL do FIRAuth.

Swift

// For iOS 9+
func application(_ application: UIApplication, open url: URL,
    options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
  if Auth.auth().canHandle(url) {
    return true
  }
  // URL not auth related, developer should handle it.
}

// For iOS 8-
func application(_ application: UIApplication,
                 open url: URL,
                 sourceApplication: String?,
                 annotation: Any) -> Bool {
  if Auth.auth().canHandle(url) {
    Return true
  }
  // URL not auth related, developer should handle it.
}

Objective-C

// For iOS 9+
- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
  if ([[FIRAuth auth] canHandleURL:url]) {
    return YES;
  }
  // URL not auth related, developer should handle it.
}

// For iOS 8-
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
  if ([[FIRAuth auth] canHandleURL:url]) {
    return YES;
  }
  // URL not auth related, developer should handle it.
}

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 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 quais dados ele 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 gerenciamento dos possíveis erros de autenticação. Consulte Solucionar erros.