Valider des numéros de téléphone sur le Web avec l'API WebOTP

Aider les utilisateurs à utiliser les codes OTP reçus par SMS

Qu'est-ce que l'API WebOTP ?

De nos jours, la plupart des personnes dans le monde possèdent un appareil mobile, et les développeurs utilisent généralement les numéros de téléphone comme identifiant des utilisateurs de leurs services.

Il existe différentes façons de valider des numéros de téléphone, mais un mot de passe à usage unique (OTP) généré de manière aléatoire et envoyé par SMS est l'une des méthodes les plus courantes. L'envoi de ce code au serveur du développeur démontre le contrôle du numéro de téléphone.

Cette idée est déjà déployée dans de nombreux scénarios pour:

  • Numéro de téléphone comme identifiant de l'utilisateur Lorsque vous vous inscrivez à un nouveau service, certains sites Web demandent un numéro de téléphone au lieu d'une adresse e-mail et l'utilisent comme identifiant de compte.
  • Validation en deux étapes Lors de la connexion, un site Web demande un code à usage unique envoyé par SMS en plus d'un mot de passe ou d'un autre facteur de connaissance pour plus de sécurité.
  • Confirmation du paiement. Lorsqu'un utilisateur effectue un paiement, demander un code à usage unique envoyé par SMS peut aider à vérifier son intention.

Le processus actuel crée des frictions pour les utilisateurs. Trouver un code OTP dans un message SMS, puis le copier et le coller dans le formulaire est une tâche fastidieuse qui réduit les taux de conversion dans les parcours utilisateur critiques. De nombreux grands développeurs mondiaux demandent depuis longtemps de faciliter ce processus pour le Web. Android dispose d'une API qui fait exactement cela. iOS et Safari font de même.

L'API WebOTP permet à votre application de recevoir des messages au format spécial associés au domaine de votre application. Vous pouvez ainsi obtenir un code à usage unique de manière programmatique à partir d'un message SMS et valider plus facilement le numéro de téléphone de l'utilisateur.

Démonstration

Supposons qu'un utilisateur souhaite valider son numéro de téléphone auprès d'un site Web. Le site Web envoie un message texte à l'utilisateur par SMS, et l'utilisateur saisit le code OTP du message pour confirmer la propriété du numéro de téléphone.

Avec l'API WebOTP, l'utilisateur n'a qu'à appuyer sur un bouton pour effectuer ces étapes, comme le montre la vidéo. Lorsque le message arrive, une bottom sheet s'affiche et invite l'utilisateur à valider son numéro de téléphone. Après avoir cliqué sur le bouton Valider dans la feuille du bas, le navigateur colle le code OTP dans le formulaire et l'envoie sans que l'utilisateur ait besoin d'appuyer sur Continuer.

L'ensemble du processus est représenté dans le schéma ci-dessous.

Diagramme de l'API WebOTP

Essayez la démo par vous-même. Il ne vous demande pas votre numéro de téléphone ni n'envoie de SMS sur votre appareil, mais vous pouvez en envoyer un depuis un autre appareil en copiant le texte affiché dans la démonstration. Cela fonctionne, car l'identité de l'expéditeur n'a pas d'importance lorsque vous utilisez l'API WebOTP.

  1. Accédez à https://web-otp.glitch.me dans Chrome 84 ou version ultérieure sur un appareil Android.
  2. Envoyez le SMS suivant à votre téléphone depuis un autre téléphone.
Your OTP is: 123456.

@web-otp.glitch.me #12345

Avez-vous reçu le SMS et l'invite vous demandant de saisir le code dans la zone de saisie ? C'est ainsi que l'API WebOTP fonctionne pour les utilisateurs.

L'utilisation de l'API WebOTP se compose de trois parties:

  • Balise <input> correctement annotée
  • JavaScript dans votre application Web
  • Texte de message mis en forme envoyé par SMS.

Je vais d'abord aborder la balise <input>.

Annoter une balise <input>

WebOTP fonctionne sans aucune annotation HTML, mais pour la compatibilité entre les navigateurs, nous vous recommandons vivement d'ajouter autocomplete="one-time-code" à la balise <input> où l'utilisateur doit saisir un code OTP.

Cela permet à Safari 14 ou version ultérieure de suggérer à l'utilisateur de remplir automatiquement le champ <input> avec un code OTP lorsqu'il reçoit un SMS au format décrit dans la section Formater le message SMS, même s'il n'est pas compatible avec WebOTP.

HTML

<form>
  <input autocomplete="one-time-code" required/>
  <input type="submit">
</form>

Utiliser l'API WebOTP

Étant donné que WebOTP est simple, il suffit de copier et de coller le code suivant. Je vais vous expliquer ce qui se passe.

JavaScript

if ('OTPCredential' in window) {
  window.addEventListener('DOMContentLoaded', e => {
    const input = document.querySelector('input[autocomplete="one-time-code"]');
    if (!input) return;
    const ac = new AbortController();
    const form = input.closest('form');
    if (form) {
      form.addEventListener('submit', e => {
        ac.abort();
      });
    }
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
      input.value = otp.code;
      if (form) form.submit();
    }).catch(err => {
      console.log(err);
    });
  });
}

Détection de fonctionnalités

La détection des fonctionnalités est identique à celle de nombreuses autres API. L'écoute de l'événement DOMContentLoaded attend que l'arborescence DOM soit prête à être interrogée.

JavaScript

if ('OTPCredential' in window) {
  window.addEventListener('DOMContentLoaded', e => {
    const input = document.querySelector('input[autocomplete="one-time-code"]');
    if (!input) return;
    
    const form = input.closest('form');
    
  });
}

Traiter l'OTP

L'API WebOTP elle-même est assez simple. Utilisez navigator.credentials.get() pour obtenir l'OTP. WebOTP ajoute une nouvelle option otp à cette méthode. Il ne comporte qu'une seule propriété: transport, dont la valeur doit être un tableau avec la chaîne 'sms'.

JavaScript

    …
    navigator.credentials.get({
      otp: { transport:['sms'] }
      …
    }).then(otp => {
    …

Cela déclenche le flux d'autorisation du navigateur lorsqu'un message SMS arrive. Si l'autorisation est accordée, la promesse renvoyée est résolue avec un objet OTPCredential.

Contenu de l'objet OTPCredential obtenu

{
  code: "123456" // Obtained OTP
  type: "otp"  // `type` is always "otp"
}

Transmettez ensuite la valeur de l'OTP au champ <input>. En envoyant directement le formulaire, l'utilisateur n'aura plus besoin d'appuyer sur un bouton.

JavaScript

    
    navigator.credentials.get({
      otp: { transport:['sms'] }
      
    }).then(otp => {
      input.value = otp.code;
      if (form) form.submit();
    }).catch(err => {
      console.error(err);
    });
    

Arrêter le message

Si l'utilisateur saisit manuellement un code OTP et envoie le formulaire, vous pouvez annuler l'appel get() à l'aide d'une instance AbortController dans l'objet options.

JavaScript

    
    const ac = new AbortController();
    
    if (form) {
      form.addEventListener('submit', e => {
        ac.abort();
      });
    }
    
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
    

Mettre en forme le message SMS

L'API elle-même devrait sembler assez simple, mais vous devez connaître quelques points avant de l'utiliser. Le message doit être envoyé après l'appel de navigator.credentials.get() et être reçu sur l'appareil où get() a été appelé. Enfin, le message doit respecter le format suivant:

  • Le message commence par un texte lisible par l'homme (facultatif) qui contient une chaîne alphanumérique de quatre à dix caractères avec au moins un chiffre, laissant la dernière ligne pour l'URL et le code OTP.
  • La partie domaine de l'URL du site Web qui a appelé l'API doit être précédée de @.
  • L'URL doit contenir un symbole dièse (#) suivi du code OTP.

Exemple :

Your OTP is: 123456.

@www.example.com #123456

Voici quelques exemples de mauvaises pratiques:

Exemple de texte SMS incorrect Pourquoi cette méthode ne fonctionne-t-elle pas ?
Here is your code for @example.com #123456 @ doit être le premier caractère de la dernière ligne.
Your code for @example.com is #123456 @ doit être le premier caractère de la dernière ligne.
Your verification code is 123456

@example.com\t#123456
Un seul espace est attendu entre @host et #code.
Your verification code is 123456

@example.com  #123456
Un seul espace est attendu entre @host et #code.
Your verification code is 123456

@ftp://example.com #123456
Vous ne pouvez pas inclure de schéma d'URL.
Your verification code is 123456

@https://example.com #123456
Vous ne pouvez pas inclure de schéma d'URL.
Your verification code is 123456

@example.com:8080 #123456
Le port ne peut pas être inclus.
Your verification code is 123456

@example.com/foobar #123456
Vous ne pouvez pas inclure de chemin.
Your verification code is 123456

@example .com #123456
Aucun espace blanc dans le domaine.
Your verification code is 123456

@domain-forbiden-chars-#%/:<>?@[] #123456
Aucun caractère interdit dans le domaine.
@example.com #123456

Mambo Jumbo
@host et #code doivent être la dernière ligne.
@example.com #123456

App hash #oudf08lkjsdf834
@host et #code doivent être la dernière ligne.
Your verification code is 123456

@example.com 123456
# manquant.
Your verification code is 123456

example.com #123456
@ manquant.
Hi mom, did you receive my last text @ et # manquants.

Démonstrations

Essayez différents messages avec la démonstration : https://web-otp.glitch.me

Vous pouvez également créer une branche et créer votre propre version : https://glitch.com/edit/#!/web-otp.

Utiliser WebOTP à partir d'un iFrame cross-origin

La saisie d'un code OTP par SMS dans une iframe inter-origines est généralement utilisée pour la confirmation de paiement, en particulier avec 3D Secure. Disposant d'un format commun pour prendre en charge les iFrames inter-origines, l'API WebOTP fournit des OTP liés à des origines imbriquées. Exemple :

  • Un utilisateur se rend sur shop.example pour acheter une paire de chaussures avec une carte de crédit.
  • Après avoir saisi le numéro de carte de crédit, le fournisseur de paiement intégré affiche un formulaire de bank.example dans un iframe demandant à l'utilisateur de valider son numéro de téléphone pour un paiement rapide.
  • bank.example envoie un SMS contenant un code à usage unique à l'utilisateur afin qu'il puisse le saisir pour valider son identité.

Pour utiliser l'API WebOTP à partir d'un iframe inter-origine, vous devez effectuer deux opérations:

  • Annotez à la fois l'origine du frame supérieur et l'origine de l'iFrame dans le message texte du SMS.
  • Configurez la stratégie d'autorisation pour autoriser l'iframe inter-origine à recevoir directement l'OTP de l'utilisateur.
Utilisation de l'API WebOTP dans un iFrame.

Vous pouvez essayer la démonstration à l'adresse https://web-otp-iframe-demo.stackblitz.io.

Annoter les origines liées au message texte par SMS

Lorsque l'API WebOTP est appelée à partir d'un iFrame, le message SMS doit inclure l'origine du frame supérieur précédée de @, suivie de l'OTP précédé de # et de l'origine de l'iFrame précédée de @ à la dernière ligne.

Your verification code is 123456

@shop.example #123456 @bank.exmple

Configurer la stratégie d'autorisation

Pour utiliser WebOTP dans un iFrame multi-origine, l'intégrateur doit accorder l'accès à cette API via la règle d'autorisation des identifiants otp pour éviter tout comportement involontaire. En général, il existe deux façons d'y parvenir:

via l'en-tête HTTP:

Permissions-Policy: otp-credentials=(self "https://bank.example")

via l'attribut allow de l'iFrame:

<iframe src="https://bank.example/…" allow="otp-credentials"></iframe>

Pour obtenir d'autres exemples de spécification d'une stratégie d'autorisation , consultez cette page.

Utiliser WebOTP sur un ordinateur

Dans Chrome, WebOTP permet d'écouter les SMS reçus sur d'autres appareils pour aider les utilisateurs à valider leur numéro de téléphone sur ordinateur.

API WebOTP sur ordinateur.

Pour utiliser cette fonctionnalité, l'utilisateur doit se connecter au même compte Google sur Chrome pour ordinateur et Chrome pour Android.

Il suffit aux développeurs d'implémenter l'API WebOTP sur leur site Web pour ordinateur, comme ils le font sur leur site Web mobile, sans avoir à utiliser d'astuces spéciales.

Pour en savoir plus, consultez Valider un numéro de téléphone sur ordinateur à l'aide de l'API WebOTP.

Questions fréquentes

La boîte de dialogue ne s'affiche pas, même si j'envoie un message correctement formaté. Que se passe-t-il ?

Quelques mises en garde concernant le test de l'API:

  • Si le numéro de téléphone de l'expéditeur est inclus dans la liste de contacts du destinataire, cette API ne sera pas déclenchée en raison de la conception de l'API SMS User Consent sous-jacente.
  • Si vous utilisez un profil professionnel sur votre appareil Android et que le WebOTP ne fonctionne pas, essayez d'installer et d'utiliser Chrome sur votre profil personnel (c'est-à-dire le même profil que celui dans lequel vous recevez des messages SMS).

Vérifiez le format pour vous assurer que votre SMS est correctement mis en forme.

Cette API est-elle compatible entre différents navigateurs ?

Chromium et WebKit se sont mis d'accord sur le format des SMS, et Apple a annoncé la prise en charge de ce format par Safari à partir d'iOS 14 et de macOS Big Sur. Bien que Safari ne prenne pas en charge l'API JavaScript WebOTP, en annotant l'élément input avec autocomplete=["one-time-code"], le clavier par défaut vous suggère automatiquement de saisir le code OTP si le message SMS est conforme au format.

Est-il sûr d'utiliser les SMS pour s'authentifier ?

Bien que le code OTP par SMS soit utile pour valider un numéro de téléphone lorsqu'il est fourni pour la première fois, la validation du numéro de téléphone par SMS doit être utilisée avec précaution pour la réauthentification, car les opérateurs peuvent le pirater et le recycler. WebOTP est un mécanisme pratique de réauthentification et de récupération, mais les services doivent le combiner à des facteurs supplémentaires, tels qu'un défi de connaissances, ou utiliser l'API Web Authentication pour une authentification forte.

Où puis-je signaler les bugs d'implémentation de Chrome ?

Avez-vous trouvé un bug dans l'implémentation de Chrome ?

  • Signalez un bug sur crbug.com. Fournissez autant de détails que possible, des instructions simples pour reproduire le problème et définissez Components sur Blink>WebOTP.

Comment puis-je améliorer cette fonctionnalité ?

Comptez-vous utiliser l'API WebOTP ? Votre soutien public nous aide à hiérarchiser les fonctionnalités et montre aux autres fournisseurs de navigateurs à quel point il est essentiel de les prendre en charge. Envoyez un tweet à @ChromiumDev en utilisant le hashtag #WebOTP et indiquez-nous où et comment vous l'utilisez.

Ressources