S'authentifier avec Firebase à l'aide d'un numéro de téléphone et de C++

Vous pouvez utiliser Firebase Authentication pour connecter un utilisateur en lui envoyant un SMS sur son téléphone. L'utilisateur se connecte à l'aide d'un code à usage unique contenu dans le message SMS.

Ce document explique comment implémenter un flux de connexion avec un numéro de téléphone à l'aide du SDK Firebase.

Avant de commencer

  1. Ajoutez Firebase à votre projet C++.
  2. Si vous n'avez pas encore associé votre application à votre projet Firebase, faites-le depuis la console Firebase.
  3. Comprenez les exigences de la plate-forme pour la connexion par numéro de téléphone :
    • La connexion par numéro de téléphone n'est disponible que sur les plates-formes mobiles.
    • Sur iOS, la connexion par numéro de téléphone nécessite un appareil physique et ne fonctionne pas sur un simulateur.

Problèmes de sécurité

L'authentification à l'aide d'un numéro de téléphone uniquement, bien que pratique, est moins sécurisée que les autres méthodes disponibles, car la possession d'un numéro de téléphone peut être facilement transférée entre les utilisateurs. De plus, sur les appareils comportant plusieurs profils utilisateur, tout utilisateur pouvant recevoir des SMS peut se connecter à un compte à l'aide du numéro de téléphone de l'appareil.

Si vous utilisez la connexion par numéro de téléphone dans votre application, vous devez la proposer en plus de méthodes de connexion plus sécurisées et informer les utilisateurs des compromis de sécurité liés à l'utilisation de la connexion par numéro de téléphone.

Activer la connexion par numéro de téléphone pour votre projet Firebase

Pour connecter les utilisateurs par SMS, vous devez d'abord activer la méthode de connexion par numéro de téléphone pour votre projet Firebase :

  1. Dans la console Firebase, accédez à Sécurité > Authentification.
  2. Dans l'onglet Méthode de connexion, activez le fournisseur de connexion Téléphone.
  3. Définissez une règle sur les régions vers lesquelles vous souhaitez autoriser ou interdire l'envoi de messages SMS. Définir une règle régionale pour les SMS peut vous aider à protéger vos applications contre l'utilisation abusive des SMS. Pour les nouveaux projets, la règle par défaut n'autorise aucune région.
    1. Dans la consoleFirebase, accédez à l'onglet Paramètres : Sécurité > Authentification.
    2. Dans la section Règles pour les SMS par région, configurez vos règles pour les SMS par région.

Commencer à recevoir des notifications APNs (plates-formes Apple)

Pour utiliser l'authentification par numéro de téléphone sur les plates-formes Apple, votre application doit pouvoir recevoir des notifications APNs de Firebase. Lorsque vous connectez un utilisateur avec son numéro de téléphone pour la première fois sur un appareil, Firebase Authentication envoie une notification push silencieuse à l'appareil pour vérifier que la demande de connexion avec le numéro de téléphone provient de votre application. (C'est pourquoi la connexion avec un numéro de téléphone ne peut pas être utilisée sur un simulateur.)

Pour activer les notifications APNs à utiliser avec Firebase Authentication :

  1. Dans Xcode, activez les notifications push pour votre projet.
  2. Importez votre certificat APNs dans Firebase. Si vous n'avez pas encore de certificat APNs, veillez à en créer un dans le Centre des membres Apple Developer.

    1. Dans la consoleFirebase, accédez à Paramètres > Général. Cliquez ensuite sur l'onglet Cloud Messaging.
    2. Cliquez sur Importer un certificat pour votre certificat de développement, votre certificat de production ou les deux. Veuillez en indiquer au moins un.
    3. Pour chaque certificat, sélectionnez le fichier .p12 et indiquez le mot de passe, le cas échéant. Assurez-vous que l'ID du bundle de ce certificat correspond à celui de votre application, puis cliquez sur Enregistrer.

Envoyer un code de validation sur le téléphone de l'utilisateur

Pour lancer la connexion avec un numéro de téléphone, présentez à l'utilisateur une interface qui l'invite à fournir son numéro de téléphone, puis appelez PhoneAuthProvider::VerifyPhoneNumber pour demander à Firebase d'envoyer un code d'authentification au téléphone de l'utilisateur par SMS :

  1. Obtenez le numéro de téléphone de l'utilisateur.

    Les exigences légales varient, mais en guise de bonne pratique et pour définir les attentes de vos utilisateurs, vous devez les informer que s'ils utilisent la connexion par téléphone, ils peuvent recevoir un message SMS pour la validation et que les tarifs standards s'appliquent.

  2. Appelez PhoneAuthProvider::VerifyPhoneNumber en lui transmettant le numéro de téléphone de l'utilisateur.
    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);
    Lorsque vous appelez PhoneAuthProvider::VerifyPhoneNumber, Firebase,
    • (sur iOS) envoie une notification push silencieuse à votre application.
    • envoie un SMS contenant un code d'authentification au numéro de téléphone spécifié et transmet un ID de validation à votre fonction d'achèvement. Vous aurez besoin du code de validation et de l'ID de validation pour connecter l'utilisateur.
  3. Enregistrez l'ID de validation et restaurez-le lorsque votre application se charge. Vous pouvez ainsi vous assurer de toujours disposer d'un ID de validation valide si votre application est arrêtée avant que l'utilisateur ait terminé le flux de connexion (par exemple, lors du passage à l'application de SMS).

    Vous pouvez conserver l'ID de validation comme vous le souhaitez. Si vous écrivez avec un framework C++ multiplate-forme, il doit fournir des notifications pour l'arrêt et la restauration de l'application. Pour ces événements, vous pouvez respectivement enregistrer et restaurer l'ID de validation.

Si l'appel à VerifyPhoneNumber entraîne l'appel de OnCodeSent sur votre écouteur, vous pouvez inviter l'utilisateur à saisir le code de validation lorsqu'il le reçoit dans le message SMS.

En revanche, si l'appel à VerifyPhoneNumber génère OnVerificationCompleted, la validation automatique a réussi et vous disposez désormais d'un PhoneAuthCredential que vous pouvez utiliser comme décrit ci-dessous.

Connecter l'utilisateur avec le code de validation

Une fois que l'utilisateur a fourni à votre application le code de validation du message SMS, connectez-le en créant un objet PhoneAuthCredential à partir du code de validation et de l'ID de validation, puis en transmettant cet objet à Auth::SignInWithCredential.

  1. Obtenez le code de validation auprès de l'utilisateur.
  2. Créez un objet Credential à partir du code de validation et de l'ID de validation.
    PhoneAuthCredential credential = phone_auth_provider->GetCredential(
        verification_id_.c_str(), verification_code.c_str());
        
  3. Connectez l'utilisateur avec l'objet 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);

Étapes suivantes

Lorsqu'un utilisateur se connecte pour la première fois, un nouvel utilisateur est créé et associé aux identifiants (nom d'utilisateur et mot de passe, numéro de téléphone ou informations du fournisseur d'authentification) avec lesquels il s'est connecté. Ce nouveau compte est stocké dans votre projet Firebase et peut être utilisé pour identifier un utilisateur dans toutes les applications de votre projet, quelle que soit la méthode de connexion de l'utilisateur.

  • Dans vos applications, vous pouvez obtenir les informations de base du profil de l'utilisateur à partir de l'objet 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();
    }
  • Dans vos Firebase Realtime Database et Cloud Storage Règles de sécurité, vous pouvez obtenir l'ID utilisateur unique de l'utilisateur connecté à partir de la variable auth, et l'utiliser pour contrôler les données auxquelles un utilisateur peut accéder.

Vous pouvez autoriser les utilisateurs à se connecter à votre application à l'aide de plusieurs fournisseurs d'authentification en associant les identifiants du fournisseur d'authentification à un compte utilisateur existant.

Pour déconnecter un utilisateur, appelez SignOut() :

auth->SignOut();