Esegui l'autenticazione con Firebase utilizzando un numero di telefono e C++

Puoi utilizzare Firebase Authentication per consentire l'accesso a un utente inviando un messaggio SMS al suo telefono. L'utente accede utilizzando un codice monouso contenuto nel messaggio SMS.

Questo documento descrive come implementare un flusso di accesso con numero di telefono utilizzando l'SDK Firebase.

Prima di iniziare

  1. Aggiungi Firebase al tuo progetto C++.
  2. Se non hai ancora connesso la tua app al progetto Firebase, fallo dalla console Firebase.
  3. Comprendi i requisiti della piattaforma per l'accesso con il numero di telefono:
    • L'accesso tramite numero di telefono è disponibile solo per le piattaforme mobile.
    • Su iOS, l'accesso con il numero di telefono richiede un dispositivo fisico e non funziona su un simulatore.

Problemi di sicurezza

L'autenticazione che utilizza solo un numero di telefono, sebbene comoda, è meno sicura rispetto agli altri metodi disponibili, perché la proprietà di un numero di telefono può essere facilmente trasferita tra gli utenti. Inoltre, sui dispositivi con più profili utente, qualsiasi utente che può ricevere messaggi SMS può accedere a un account utilizzando il numero di telefono del dispositivo.

Se utilizzi l'accesso basato sul numero di telefono nella tua app, devi offrirlo insieme a metodi di accesso più sicuri e informare gli utenti dei compromessi in termini di sicurezza dell'utilizzo dell'accesso con il numero di telefono.

Attivare l'accesso con numero di telefono per il tuo progetto Firebase

Per consentire agli utenti di accedere tramite SMS, devi prima attivare il metodo di accesso con numero di telefono per il tuo progetto Firebase:

  1. Nella Firebaseconsole, apri la sezione Autenticazione.
  2. Nella pagina Metodo di accesso, attiva il metodo di accesso Numero di telefono.
  3. (Facoltativo) Nella pagina Impostazioni, imposta un criterio per le regioni a cui vuoi consentire o negare l'invio di messaggi SMS. L'impostazione di una norma regionale per gli SMS può contribuire a proteggere le tue app dall'abuso di SMS.

Iniziare a ricevere le notifiche APN (piattaforme Apple)

Per utilizzare l'autenticazione tramite numero di telefono sulle piattaforme Apple, la tua app deve essere in grado di ricevere notifiche APN da Firebase. Quando un utente esegue l'accesso con il proprio numero di telefono per la prima volta su un dispositivo, Firebase Authentication invia una notifica push silenziosa al dispositivo per verificare che la richiesta di accesso con il numero di telefono provenga dalla tua app. Per questo motivo, l'accesso con il numero di telefono non può essere utilizzato su un simulatore.

Per attivare le notifiche APN da utilizzare con Firebase Authentication:

  1. In Xcode, attiva le notifiche push per il tuo progetto.
  2. Carica il certificato del servizio APN su Firebase. Se non hai ancora un certificato APNs, assicurati di crearne uno nel Centro membri Apple Developer.

    1. All'interno del progetto nella console Firebase, seleziona l'icona a forma di ingranaggio, seleziona Impostazioni progetto e poi la scheda Cloud Messaging.

    2. Seleziona il pulsante Carica certificato per il certificato di sviluppo, il certificato di produzione o entrambi. È obbligatorio indicare almeno un valore.

    3. Per ogni certificato, seleziona il file .p12 e fornisci la password, se presente. Assicurati che l'ID bundle per questo certificato corrisponda all'ID bundle della tua app. Seleziona Salva.

Invia un codice di verifica al telefono dell'utente

Per avviare l'accesso con il numero di telefono, mostra all'utente un'interfaccia che gli chiede di fornire il proprio numero di telefono, quindi chiama PhoneAuthProvider::VerifyPhoneNumber per richiedere a Firebase di inviare un codice di autenticazione al telefono dell'utente tramite SMS:

  1. Recupera il numero di telefono dell'utente.

    I requisiti legali variano, ma come best practice e per definire le aspettative degli utenti, devi informarli che se utilizzano l'accesso con il numero di telefono, potrebbero ricevere un messaggio SMS per la verifica e si applicano tariffe standard.

  2. Chiama PhoneAuthProvider::VerifyPhoneNumber, passando il numero di telefono dell'utente.
    class PhoneListener : public PhoneAuthProvider::Listener {
     public:
      ~PhoneListener() override {}
    
      void OnVerificationCompleted(PhoneAuthCredential credential) override {
        // Auto-sms-retrieval or instant validation has succeeded (Android only).
        // No need for the user to input the verification code manually.
        // `credential` can be used instead of calling GetCredential().
      }
    
      void OnVerificationFailed(const std::string& error) override {
        // Verification code not sent.
      }
    
      void OnCodeSent(const std::string& verification_id,
                      const PhoneAuthProvider::ForceResendingToken&
                          force_resending_token) override {
        // Verification code successfully sent via SMS.
        // Show the Screen to enter the Code.
        // Developer may want to save that verification_id along with other app states in case
        // the app is terminated before the user gets the SMS verification code.
      }
    };
    
    PhoneListener phone_listener;
    PhoneAuhtOptions options;
    options.timeout_milliseconds = kAutoVerifyTimeOut;
    options.phone_number = phone_number;
    PhoneAuthProvider& phone_provider = PhoneAuthProvider::GetInstance(auth);
    phone_provider->VerifyPhoneNumber(options, &phone_listener);
    Quando chiami PhoneAuthProvider::VerifyPhoneNumber, Firebase,
    • (su iOS) invia una notifica push silenziosa alla tua app,
    • invia un messaggio SMS contenente un codice di autenticazione al numero di telefono specificato e passa un ID di verifica alla funzione di completamento. Per accedere, l'utente avrà bisogno sia del codice di verifica sia dell'ID verifica.
  3. Salva l'ID verifica e ripristinalo quando l'app viene caricata. In questo modo, puoi assicurarti di avere ancora un ID di verifica valido se la tua app viene terminata prima che l'utente completi il flusso di accesso (ad esempio, durante il passaggio all'app di messaggistica).

    Puoi archiviare l'ID verifica nel modo che preferisci. Se scrivi con un framework C++ multipiattaforma, questo dovrebbe fornire notifiche per l'interruzione e il ripristino dell'app. In questi eventi, puoi salvare e ripristinare, rispettivamente, l'ID verifica.

Se la chiamata a VerifyPhoneNumber comporta la chiamata a OnCodeSent sul tuo Listener, puoi chiedere all'utente di digitare il codice di verifica quando lo riceve nel messaggio SMS.

D'altra parte, se la chiamata a VerifyPhoneNumber restituisce OnVerificationCompleted, la verifica automatica è riuscita e ora avrai un PhoneAuthCredential che potrai utilizzare come descritto di seguito.

Accedere all'utente con il codice di verifica

Dopo che l'utente ha fornito alla tua app il codice di verifica dell'SMS, accedi all'utente creando un oggetto PhoneAuthCredential dal codice di verifica e dall'ID verifica e passando l'oggetto a Auth::SignInWithCredential.

  1. Ottieni il codice di verifica dall'utente.
  2. Crea un oggetto Credential dal codice di verifica e dall'ID verifica.
    PhoneAuthCredential credential = phone_auth_provider->GetCredential(
        verification_id_.c_str(), verification_code.c_str());
        
  3. Consenti l'accesso all'utente con l'oggetto Credential:
    Future<User> future = auth_->SignInWithCredential(credential);
    future.OnCompletion(
        [](const Future<User*>& result, void*) {
          if (result.error() == kAuthErrorNone) {
            // Successful.
            // User is signed in.
            User user = *result.result();
    
            // This should display the phone number.
            printf("Phone number: %s", user.phone_number().c_str());
    
            // The phone number provider UID is the phone number itself.
            printf("Phone provider uid: %s", user.uid().c_str());
    
            // The phone number providerID is 'phone'
            printf("Phone provider ID: %s", user.provider_id().c_str());
          } else {
            // Error.
            printf("Sign in error: %s", result.error_message().c_str());
          }
        },
        nullptr);

Passaggi successivi

Dopo che un utente ha eseguito l'accesso per la prima volta, viene creato un nuovo account utente e collegato alle credenziali, ovvero nome utente e password, numero di telefono o informazioni del fornitore di autenticazione, con cui l'utente ha eseguito l'accesso. Questo nuovo account viene memorizzato come parte del tuo progetto Firebase e può essere utilizzato per identificare un utente in ogni app del tuo progetto, indipendentemente dalla modalità di accesso.

  • Nelle tue app, puoi ottenere le informazioni di base del profilo dell'utente dall'oggetto firebase::auth::User:

    firebase::auth::User user = auth->current_user();
    if (user.is_valid()) {
      std::string name = user.display_name();
      std::string email = user.email();
      std::string photo_url = user.photo_url();
      // The user's ID, unique to the Firebase project.
      // Do NOT use this value to authenticate with your backend server,
      // if you have one. Use firebase::auth::User::Token() instead.
      std::string uid = user.uid();
    }
  • Nelle regole di sicurezza di Firebase Realtime Database e Cloud Storage, puoi ottenere l'ID utente univoco dell'utente che ha eseguito l'accesso dalla variabile auth e utilizzarlo per controllare a quali dati può accedere un utente.

Puoi consentire agli utenti di accedere alla tua app utilizzando più provider di autenticazione collegando le credenziali del provider di autenticazione a un account utente esistente.

Per disconnettere un utente, chiama SignOut():

auth->SignOut();