Authentification par téléphone

L'authentification par téléphone permet aux utilisateurs de se connecter à Firebase à l'aide de leur téléphone comme authentificateur. Un message SMS contenant un code unique est envoyé à l'utilisateur (à l'aide du numéro de téléphone fourni). Une fois le code autorisé, l'utilisateur peut se connecter à Firebase.

Les numéros de téléphone que les utilisateurs finaux fournissent pour l'authentification seront envoyés et stockés par Google afin d'améliorer la protection contre le spam et les abus dans tous les services Google, y compris, mais sans s'y limiter, Firebase. Les développeurs doivent s'assurer d'obtenir le consentement approprié de l'utilisateur final avant d'utiliser le service de connexion par numéro de téléphone Firebase Authentication.

Firebase Authentication par téléphone n'est pas disponible dans tous les pays. Pour en savoir plus, consultez les questions fréquentes.

Prérequis

Avant de commencer à utiliser l'authentification par téléphone, assurez-vous d'avoir suivi ces étapes:

  1. Activez le téléphone comme méthode de connexion dans la console Firebase.
  2. Android: si vous n'avez pas encore défini le hachage SHA-1 de votre application dans la console Firebase, faites-le. Consultez la section Authentifier votre client pour savoir comment trouver le hachage SHA-1 de votre application.
  3. iOS: dans Xcode, activez les notifications push pour votre projet et assurez-vous que votre clé d'authentification APN est configurée avec Firebase Cloud Messaging (FCM). De plus, vous devez activer les modes en arrière-plan pour les notifications à distance. Pour obtenir une explication détaillée de cette étape, consultez la documentation sur l'authentification par téléphone Firebase sur iOS.
  4. Web: assurez-vous d'avoir ajouté le domaine de votre application dans la console Firebase, sous Domaines de redirection OAuth.

Remarque : La connexion avec un numéro de téléphone n'est disponible que sur des appareils physiques et sur le Web. Pour tester votre flux d'authentification sur des émulateurs d'appareils, consultez la section Tests.

Utilisation

Le SDK Firebase Authentication pour Flutter propose deux méthodes distinctes pour connecter un utilisateur avec son numéro de téléphone. Les plates-formes natives (Android et iOS, par exemple) proposent des fonctionnalités de validation de numéro de téléphone différentes de celles du Web. Par conséquent, deux méthodes existent exclusivement pour chaque plate-forme:

  • Plate-forme native: verifyPhoneNumber.
  • Plate-forme Web: signInWithPhoneNumber.

Native: verifyPhoneNumber

Sur les plates-formes natives, le numéro de téléphone de l'utilisateur doit d'abord être validé, puis l'utilisateur peut se connecter ou associer son compte à un PhoneAuthCredential.

Vous devez d'abord demander à l'utilisateur de saisir son numéro de téléphone. Une fois la valeur fournie, appelez la méthode verifyPhoneNumber():

await FirebaseAuth.instance.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) {},
  verificationFailed: (FirebaseAuthException e) {},
  codeSent: (String verificationId, int? resendToken) {},
  codeAutoRetrievalTimeout: (String verificationId) {},
);

Vous devez gérer quatre rappels distincts, chacun déterminant la façon dont vous mettez à jour l'UI de l'application:

  1. verificationCompleted: gestion automatique du code par SMS sur les appareils Android.
  2. verificationFailed: gérez les événements d'échec tels que les numéros de téléphone non valides ou le dépassement du quota de SMS.
  3. codeSent: permet de gérer l'envoi d'un code à l'appareil depuis Firebase, qui permet d'inviter les utilisateurs à saisir le code.
  4. codeAutoRetrievalTimeout: gère un délai avant expiration lorsque la gestion automatique du code par SMS échoue.

verificationCompleted

Ce gestionnaire ne sera appelé que sur les appareils Android compatibles avec la résolution automatique du code par SMS.

Lorsque le code SMS est envoyé à l'appareil, Android le valide automatiquement sans que l'utilisateur ait à le saisir manuellement. Si cet événement se produit, un PhoneAuthCredential est automatiquement fourni, qui peut être utilisé pour se connecter avec le numéro de téléphone de l'utilisateur ou l'associer.

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) async {
    // ANDROID ONLY!

    // Sign the user in (or link) with the auto-generated credential
    await auth.signInWithCredential(credential);
  },
);

verificationFailed

Si Firebase renvoie une erreur, par exemple en raison d'un numéro de téléphone incorrect ou si le quota de SMS du projet a été dépassé, un FirebaseAuthException est envoyé à ce gestionnaire. Dans ce cas, vous devez indiquer à l'utilisateur qu'une erreur s'est produite en fonction du code d'erreur.

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationFailed: (FirebaseAuthException e) {
    if (e.code == 'invalid-phone-number') {
      print('The provided phone number is not valid.');
    }

    // Handle other errors
  },
);

codeSent

Lorsque Firebase envoie un code par SMS à l'appareil, ce gestionnaire est déclenché avec un verificationId et un resendToken (un resendToken n'est compatible qu'avec les appareils Android. Les appareils iOS renvoient toujours une valeur null).

Une fois le déclenchement effectué, il est judicieux de mettre à jour l'interface utilisateur de votre application pour inviter l'utilisateur à saisir le code SMS qu'il attend. Une fois le code SMS saisi, vous pouvez combiner l'ID de validation avec le code SMS pour créer un PhoneAuthCredential:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  codeSent: (String verificationId, int? resendToken) async {
    // Update the UI - wait for the user to enter the SMS code
    String smsCode = 'xxxx';

    // Create a PhoneAuthCredential with the code
    PhoneAuthCredential credential = PhoneAuthProvider.credential(verificationId: verificationId, smsCode: smsCode);

    // Sign the user in (or link) with the credential
    await auth.signInWithCredential(credential);
  },
);

Par défaut, Firebase ne renvoie pas de nouveau message SMS s'il a été envoyé récemment. Vous pouvez toutefois remplacer ce comportement en appelant à nouveau la méthode verifyPhoneNumber avec le jeton de renvoi dans l'argument forceResendingToken. Si l'opération réussit, le message SMS est renvoyé.

codeAutoRetrievalTimeout

Sur les appareils Android compatibles avec la résolution automatique du code SMS, ce gestionnaire est appelé si l'appareil n'a pas résolu automatiquement un message SMS dans un certain délai. Une fois ce délai écoulé, l'appareil n'essaiera plus de résoudre les messages entrants.

Par défaut, l'appareil attend 30 secondes, mais cette valeur peut être personnalisée avec l'argument timeout:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  timeout: const Duration(seconds: 60),
  codeAutoRetrievalTimeout: (String verificationId) {
    // Auto-resolution timed out...
  },
);

Web: signInWithPhoneNumber

Sur les plates-formes Web, les utilisateurs peuvent se connecter en confirmant qu'ils ont accès à un téléphone en saisissant le code envoyé par SMS au numéro de téléphone fourni. Pour renforcer la sécurité et éviter le spam, les utilisateurs doivent prouver qu'ils sont humains en remplissant un widget Google Recaptcha. Une fois la confirmation effectuée, le code SMS sera envoyé.

Le SDK Firebase Authentication pour Flutter gère le widget reCAPTCHA par défaut, mais vous permet de contrôler son affichage et sa configuration si nécessaire. Pour commencer, appelez la méthode signInWithPhoneNumber avec le numéro de téléphone.

FirebaseAuth auth = FirebaseAuth.instance;

// Wait for the user to complete the reCAPTCHA & for an SMS code to be sent.
ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456');

L'appel de la méthode déclenche d'abord l'affichage du widget reCAPTCHA. L'utilisateur doit effectuer le test avant qu'un code par SMS ne lui soit envoyé. Une fois la procédure terminée, vous pouvez connecter l'utilisateur en fournissant le code SMS à la méthode confirm dans la réponse ConfirmationResult résolue:

UserCredential userCredential = await confirmationResult.confirm('123456');

Comme pour les autres flux de connexion, une connexion réussie déclenche tous les écouteurs d'état d'authentification auxquels vous vous êtes abonné dans votre application.

Configuration reCAPTCHA

Le widget reCAPTCHA est un flux entièrement géré qui sécurise votre application Web.

Le deuxième argument de signInWithPhoneNumber accepte une instance RecaptchaVerifier facultative qui peut être utilisée pour gérer le widget. Par défaut, le widget s'affiche comme un widget invisible lorsque le flux de connexion est déclenché. Un widget "invisible" apparaîtra sous la forme d'une fenêtre modale pleine page au-dessus de votre application.

Il est toutefois possible d'afficher un widget intégré sur lequel l'utilisateur doit appuyer explicitement pour se valider.

Pour ajouter un widget intégré, spécifiez un ID d'élément DOM à l'argument container de l'instance RecaptchaVerifier. L'élément doit exister et être vide, sinon une erreur est générée. Si aucun argument container n'est fourni, le widget est affiché comme "invisible".

ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456', RecaptchaVerifier(
  container: 'recaptcha',
  size: RecaptchaVerifierSize.compact,
  theme: RecaptchaVerifierTheme.dark,
));

Vous pouvez éventuellement modifier la taille et le thème en personnalisant les arguments size et theme, comme indiqué ci-dessus.

Il est également possible d'écouter des événements, par exemple pour savoir si l'utilisateur a terminé le reCAPTCHA, si le reCAPTCHA a expiré ou si une erreur s'est produite:

RecaptchaVerifier(
  onSuccess: () => print('reCAPTCHA Completed!'),
  onError: (FirebaseAuthException error) => print(error),
  onExpired: () => print('reCAPTCHA Expired!'),
);

Tests

Firebase permet de tester les numéros de téléphone localement:

  1. Dans la console Firebase, sélectionnez le fournisseur d'authentification "Téléphone", puis cliquez sur la liste déroulante "Numéros de téléphone à des fins de test".
  2. Saisissez un nouveau numéro de téléphone (par exemple, +44 7444 555666) et un code de test (par exemple, 123456).

Si vous fournissez un numéro de téléphone de test aux méthodes verifyPhoneNumber ou signInWithPhoneNumber, aucun SMS ne sera envoyé. Vous pouvez plutôt fournir le code de test directement à PhoneAuthProvider ou avec le gestionnaire de résultats de confirmation de signInWithPhoneNumber.