Authentifiez-vous avec Firebase avec un numéro de téléphone à l'aide de JavaScript

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

Le moyen le plus simple d'ajouter une connexion par numéro de téléphone à votre application consiste à utiliser FirebaseUI , qui comprend un widget de connexion déroulant qui implémente des flux de connexion pour la connexion par numéro de téléphone, ainsi qu'une connexion fédérée et basée sur un mot de passe. -dans. Ce document décrit comment implémenter un flux de connexion par numéro de téléphone à l'aide du SDK Firebase.

Avant que tu commences

Si vous ne l'avez pas déjà fait, copiez l'extrait d'initialisation de la console Firebase vers votre projet, comme décrit dans Ajouter Firebase à votre projet JavaScript .

Problèmes de sécurité

L'authentification utilisant uniquement un numéro de téléphone, 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 utilisateurs. De plus, sur les appareils dotés de plusieurs profils utilisateur, tout utilisateur pouvant recevoir des messages 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 parallèlement à des méthodes de connexion plus sécurisées et informer les utilisateurs des compromis en matière 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 des 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 , ouvrez la section Authentification .
  2. Sur la page Méthode de connexion , activez la méthode de connexion par numéro de téléphone .
  3. Sur la même page, si le domaine qui hébergera votre application n'est pas répertorié dans la section Domaines de redirection OAuth , ajoutez votre domaine.

Le quota de demandes de connexion par numéro de téléphone de Firebase est suffisamment élevé pour que la plupart des applications ne soient pas affectées. Toutefois, si vous devez connecter un très grand nombre d’utilisateurs avec l’authentification téléphonique, vous devrez peut-être mettre à niveau votre plan tarifaire. Voir la page des tarifs .

Configurer le vérificateur reCAPTCHA

Avant de pouvoir connecter des utilisateurs avec leur numéro de téléphone, vous devez configurer le vérificateur reCAPTCHA de Firebase. Firebase utilise reCAPTCHA pour éviter les abus, par exemple en garantissant que la demande de vérification du numéro de téléphone provient de l'un des domaines autorisés de votre application.

Vous n'avez pas besoin de configurer manuellement un client reCAPTCHA ; lorsque vous utilisez l'objet RecaptchaVerifier du SDK Firebase, Firebase crée et gère automatiquement toutes les clés et secrets client nécessaires.

L'objet RecaptchaVerifier prend en charge le reCAPTCHA invisible , qui peut souvent vérifier l'utilisateur sans nécessiter aucune action de l'utilisateur, ainsi que le widget reCAPTCHA, qui nécessite toujours une interaction de l'utilisateur pour réussir.

Le reCAPTCHA rendu sous-jacent peut être localisé selon les préférences de l'utilisateur en mettant à jour le code de langue sur l'instance Auth avant de restituer le reCAPTCHA. La localisation susmentionnée s'appliquera également au message SMS envoyé à l'utilisateur, contenant le code de vérification.

Web modular API

import { getAuth } from "firebase/auth";

const auth = getAuth();
auth.languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// auth.useDeviceLanguage();

Web namespaced API

firebase.auth().languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// firebase.auth().useDeviceLanguage();

Utiliser reCAPTCHA invisible

Pour utiliser un reCAPTCHA invisible, créez un objet RecaptchaVerifier avec le paramètre size défini sur invisible , en spécifiant l'ID du bouton qui soumet votre formulaire de connexion. Par exemple:

Web modular API

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

Web namespaced API

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

Utilisez le widget reCAPTCHA

Pour utiliser le widget reCAPTCHA visible, créez un élément sur votre page pour contenir le widget, puis créez un objet RecaptchaVerifier , en spécifiant l'ID du conteneur lorsque vous le faites. Par exemple:

Web modular API

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {});

Web namespaced API

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');

Facultatif : Spécifiez les paramètres reCAPTCHA

Vous pouvez éventuellement définir des fonctions de rappel sur l'objet RecaptchaVerifier qui sont appelées lorsque l'utilisateur résout le reCAPTCHA ou que le reCAPTCHA expire avant que l'utilisateur ne soumette le formulaire :

Web modular API

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

Web namespaced API

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

Facultatif : pré-afficher le reCAPTCHA

Si vous souhaitez pré-afficher le reCAPTCHA avant de soumettre une demande de connexion, appelez render :

Web modular API

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

Web namespaced API

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

Une fois render résolu, vous obtenez l'ID du widget reCAPTCHA, que vous pouvez utiliser pour appeler l'API reCAPTCHA :

Web modular API

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Web namespaced API

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Envoyer un code de vérification au téléphone de l'utilisateur

Pour lancer la connexion par 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 signInWithPhoneNumber 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 à titre 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 vérification et que les tarifs standard s'appliquent.

  2. Appelez signInWithPhoneNumber , en lui transmettant le numéro de téléphone de l'utilisateur et le RecaptchaVerifier que vous avez créé précédemment.

    Web modular API

    import { getAuth, signInWithPhoneNumber } from "firebase/auth";
    
    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    
    const auth = getAuth();
    signInWithPhoneNumber(auth, phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });

    Web namespaced API

    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });
    Si signInWithPhoneNumber génère une erreur, réinitialisez le reCAPTCHA pour que l'utilisateur puisse réessayer :
    grecaptcha.reset(window.recaptchaWidgetId);
    
    // Or, if you haven't stored the widget ID:
    window.recaptchaVerifier.render().then(function(widgetId) {
      grecaptcha.reset(widgetId);
    });
    

La méthode signInWithPhoneNumber envoie le défi reCAPTCHA à l'utilisateur et, si l'utilisateur réussit le défi, demande à l'authentification Firebase d'envoyer un message SMS contenant un code de vérification au téléphone de l'utilisateur.

Connectez l'utilisateur avec le code de vérification

Une fois l’appel à signInWithPhoneNumber réussi, invitez l’utilisateur à saisir le code de vérification qu’il a reçu par SMS. Ensuite, connectez l'utilisateur en transmettant le code à la méthode confirm de l'objet ConfirmationResult qui a été transmis au gestionnaire d'exécution de signInWithPhoneNumber (c'est-à-dire son bloc then ). Par exemple:

Web modular API

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

Web namespaced API

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

Si l’appel de confirm réussit, l’utilisateur est connecté avec succès.

Récupérer l'objet AuthCredential intermédiaire

Si vous avez besoin d'obtenir un objet AuthCredential pour le compte de l'utilisateur, transmettez le code de vérification du résultat de la confirmation et le code de vérification à PhoneAuthProvider.credential au lieu d'appeler confirm :

var credential = firebase.auth.PhoneAuthProvider.credential(confirmationResult.verificationId, code);

Ensuite, vous pouvez connecter l'utilisateur avec les informations d'identification :

firebase.auth().signInWithCredential(credential);

Testez avec des numéros de téléphone fictifs

Vous pouvez configurer des numéros de téléphone fictifs pour le développement via la console Firebase. Les tests avec des numéros de téléphone fictifs offrent les avantages suivants :

  • Testez l'authentification du numéro de téléphone sans consommer votre quota d'utilisation.
  • Testez l'authentification du numéro de téléphone sans envoyer de véritable message SMS.
  • Exécutez des tests consécutifs avec le même numéro de téléphone sans être limité. Cela minimise le risque de rejet lors du processus d'examen de l'App Store si l'évaluateur utilise le même numéro de téléphone pour les tests.
  • Testez facilement dans des environnements de développement sans aucun effort supplémentaire, comme la possibilité de développer dans un simulateur iOS ou un émulateur Android sans les services Google Play.
  • Écrivez des tests d'intégration sans être bloqué par les contrôles de sécurité normalement appliqués sur de vrais numéros de téléphone dans un environnement de production.

Les numéros de téléphone fictifs doivent répondre à ces exigences :

  1. Assurez-vous d'utiliser des numéros de téléphone qui sont effectivement fictifs et qui n'existent pas déjà. L'authentification Firebase ne vous permet pas de définir les numéros de téléphone existants utilisés par de vrais utilisateurs comme numéros de test. Une option consiste à utiliser 555 numéros avec préfixe comme numéros de téléphone de test aux États-Unis, par exemple : +1 650-555-3434.
  2. Les numéros de téléphone doivent être correctement formatés en fonction de leur longueur et d'autres contraintes. Ils subiront toujours la même validation que le numéro de téléphone d'un utilisateur réel.
  3. Vous pouvez ajouter jusqu'à 10 numéros de téléphone pour le développement.
  4. Utilisez des numéros de téléphone/codes de test difficiles à deviner et modifiez-les fréquemment.

Créer des numéros de téléphone et des codes de vérification fictifs

  1. Dans la console Firebase , ouvrez la section Authentification .
  2. Dans l'onglet Méthode de connexion , activez le fournisseur de téléphone si ce n'est pas déjà fait.
  3. Ouvrez le menu Numéros de téléphone pour tester l'accordéon.
  4. Fournissez le numéro de téléphone que vous souhaitez tester, par exemple : +1 650-555-3434 .
  5. Fournissez le code de vérification à 6 chiffres pour ce numéro spécifique, par exemple : 654321 .
  6. Ajoutez le numéro. Si nécessaire, vous pouvez supprimer le numéro de téléphone et son code en survolant la ligne correspondante et en cliquant sur l'icône de la corbeille.

Tests manuels

Vous pouvez directement commencer à utiliser un numéro de téléphone fictif dans votre application. Cela vous permet d'effectuer des tests manuels pendant les étapes de développement sans rencontrer de problèmes de quota ou de limitation. Vous pouvez également tester directement à partir d'un simulateur iOS ou d'un émulateur Android sans que les services Google Play soient installés.

Lorsque vous fournissez le numéro de téléphone fictif et envoyez le code de vérification, aucun SMS réel n'est envoyé. Au lieu de cela, vous devez fournir le code de vérification précédemment configuré pour finaliser la connexion.

Une fois la connexion terminée, un utilisateur Firebase est créé avec ce numéro de téléphone. L'utilisateur a le même comportement et les mêmes propriétés qu'un utilisateur réel de numéro de téléphone et peut accéder à la base de données en temps réel/Cloud Firestore et à d'autres services de la même manière. Le jeton d'identification émis au cours de ce processus a la même signature qu'un véritable utilisateur de numéro de téléphone.

Une autre option consiste à définir un rôle de test via des revendications personnalisées sur ces utilisateurs pour les différencier en tant que faux utilisateurs si vous souhaitez restreindre davantage l'accès.

Tests d'intégration

En plus des tests manuels, Firebase Authentication fournit des API pour vous aider à rédiger des tests d'intégration pour les tests d'authentification téléphonique. Ces API désactivent la vérification des applications en désactivant l'exigence reCAPTCHA dans les notifications Web et push silencieuses dans iOS. Cela rend les tests d'automatisation possibles dans ces flux et plus faciles à mettre en œuvre. De plus, ils permettent de tester les flux de vérification instantanée sur Android.

Sur le Web, définissez appVerificationDisabledForTesting sur true avant de restituer le firebase.auth.RecaptchaVerifier . Cela résout automatiquement le reCAPTCHA, vous permettant de transmettre le numéro de téléphone sans le résoudre manuellement. Notez que même si reCAPTCHA est désactivé, l'utilisation d'un numéro de téléphone non fictif ne permettra toujours pas de se connecter. Seuls les numéros de téléphone fictifs peuvent être utilisés avec cette API.

// Turn off phone auth app verification.
firebase.auth().settings.appVerificationDisabledForTesting = true;

var phoneNumber = "+16505554567";
var testVerificationCode = "123456";

// This will render a fake reCAPTCHA as appVerificationDisabledForTesting is true.
// This will resolve after rendering without app verification.
var appVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
// signInWithPhoneNumber will call appVerifier.verify() which will resolve with a fake
// reCAPTCHA response.
firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
    .then(function (confirmationResult) {
      // confirmationResult can resolve with the fictional testVerificationCode above.
      return confirmationResult.confirm(testVerificationCode)
    }).catch(function (error) {
      // Error; SMS not sent
      // ...
    });

Les vérificateurs d'application reCAPTCHA fictifs visibles et invisibles se comportent différemment lorsque la vérification de l'application est désactivée :

  • ReCAPTCHA visible : lorsque le reCAPTCHA visible est rendu via appVerifier.render() , il se résout automatiquement après une fraction de seconde de délai. Cela équivaut à un utilisateur cliquant sur le reCAPTCHA immédiatement après le rendu. La réponse reCAPTCHA expirera après un certain temps, puis se résoudra à nouveau automatiquement.
  • ReCAPTCHA invisible : le reCAPTCHA invisible ne se résout pas automatiquement lors du rendu mais le fait lors de l'appel appVerifier.verify() ou lorsque l'on clique sur le bouton d'ancrage du reCAPTCHA après une fraction de seconde de délai. De même, la réponse expirera après un certain temps et ne se résoudra automatiquement qu'après l'appel appVerifier.verify() ou lorsque l'on cliquera à nouveau sur le bouton d'ancrage du reCAPTCHA.

Chaque fois qu'un reCAPTCHA fictif est résolu, la fonction de rappel correspondante est déclenchée comme prévu avec la fausse réponse. Si un rappel d'expiration est également spécifié, il se déclenchera à l'expiration.

Prochaines étapes

Après qu'un utilisateur se connecte pour la première fois, un nouveau compte utilisateur est créé et lié aux informations d'identification (c'est-à-dire le nom d'utilisateur et le mot de passe, le numéro de téléphone ou les informations du fournisseur d'authentification) avec lesquels l'utilisateur s'est connecté. Ce nouveau compte est stocké dans le cadre de votre projet Firebase et peut être utilisé pour identifier un utilisateur dans chaque application de votre projet, quelle que soit la manière dont l'utilisateur se connecte.

  • Dans vos applications, la méthode recommandée pour connaître le statut d'authentification de votre utilisateur consiste à définir un observateur sur l'objet Auth . Vous pouvez ensuite obtenir les informations de profil de base de l'utilisateur à partir de l'objet User . Voir Gérer les utilisateurs .

  • Dans vos règles de sécurité Firebase Realtime Database et Cloud Storage, 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 informations d'identification du fournisseur d'authentification à un compte utilisateur existant.

Pour déconnecter un utilisateur, appelez signOut :

Web modular API

import { getAuth, signOut } from "firebase/auth";

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});

Web namespaced API

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});