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

Aider les utilisateurs ayant des mots de passe à usage unique reçus par SMS

Qu'est-ce que l'API WebOTP ?

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

Il existe plusieurs façons de valider un numéro de téléphone, mais un mot de passe à usage unique (OTP, one-time password) généré de manière aléatoire et envoyé par SMS est l'une des plus courantes. Le renvoi 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à mise en œuvre dans de nombreux scénarios pour obtenir:

  • Numéro de téléphone utilisé comme identifiant pour l'utilisateur Lors de l'inscription à 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 unique envoyé par SMS en plus d'un mot de passe ou d'un autre facteur de sécurité pour plus de sécurité.
  • Confirmation du paiement. Lorsqu'un utilisateur effectue un paiement, demander un code unique envoyé par SMS peut aider à vérifier l'intention de la personne.

Le processus actuel crée des frictions pour les utilisateurs. Trouver un mot de passe à usage unique dans un SMS, puis le copier et le coller dans le formulaire est un processus fastidieux qui diminue les taux de conversion lors des parcours utilisateur critiques. De nombreux grands développeurs mondiaux demandent depuis longtemps à remédier à la situation. Android dispose d'une API qui fait exactement cela. Il en va de même pour iOS et Safari.

L'API WebOTP permet à votre application de recevoir des messages présentant un format spécifique liés au domaine de votre application. Vous pouvez alors obtenir par programmation un mot de passe à usage unique à partir d'un SMS et vérifier plus facilement le numéro de téléphone de l'utilisateur.

Démonstration

Imaginons qu'un utilisateur souhaite valider son numéro de téléphone sur un site Web. Le site Web envoie un SMS à l'utilisateur, qui saisit l'OTP à partir du message pour vérifier la propriété du numéro de téléphone.

Avec l'API WebOTP, l'utilisateur peut réaliser ces étapes en un seul geste, comme illustré dans la vidéo. À la réception du SMS, une bottom sheet s'affiche et invite l'utilisateur à valider son numéro de téléphone. Une fois que vous avez cliqué sur le bouton Valider de la bottom sheet, le navigateur colle le mot de passe à usage unique dans le formulaire. Le formulaire est envoyé sans que l'utilisateur n'ait à appuyer sur Continuer.

L'ensemble du processus est illustré sur l'image ci-dessous.

Diagramme de l'API WebOTP

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

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

@web-otp.glitch.me #12345

Avez-vous reçu le SMS et vous êtes invité à 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 fait en trois parties:

  • Une balise <input> correctement annotée
  • JavaScript dans votre application Web
  • Texte formaté du message envoyé par SMS.

Commençons par le tag <input>.

Annoter un tag <input>

WebOTP en lui-même fonctionne sans annotation HTML, mais pour des raisons de compatibilité entre les navigateurs, je vous recommande vivement d'ajouter autocomplete="one-time-code" à la balise <input> où vous attendez que l'utilisateur saisisse un mot de passe à usage unique.

Cela permet à Safari 14 ou version ultérieure de suggérer à l'utilisateur de saisir automatiquement un mot de passe à usage unique dans le champ <input> lorsqu'il reçoit un SMS au format décrit dans la section Mettre en forme le message SMS, même si WebOTP n'est pas compatible.

HTML

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

Utiliser l'API WebOTP

Comme WebOTP est simple, il vous suffit de copier et coller le code suivant. Je vais vous expliquer ce qui se passe de toute façon.

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 de caractéristiques est la même que pour de nombreuses autres API. En écoutant l'événement DOMContentLoaded, vous attendez 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 possède 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 => {
    …

Cette action déclenche le flux d'autorisation du navigateur lorsqu'un SMS arrive. Si l'autorisation est accordée, la promesse renvoyée se résout 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 dans le champ <input>. En envoyant le formulaire directement, vous n'avez 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);
    });
    …

Annulation du message...

Si l'utilisateur saisit manuellement un mot de passe à usage unique 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 SMS

L'API elle-même devrait sembler suffisamment simple, mais voici quelques points à prendre en compte avant de l'utiliser. Le message doit être envoyé après l'appel de navigator.credentials.get() et 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 (facultatif) qui contient une chaîne alphanumérique de quatre à dix caractères, avec au moins un chiffre qui laisse la dernière ligne pour l'URL et le mot de passe à usage unique.
  • 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 signe dièse ("#") suivi du mot de passe à usage unique.

Exemple :

Your OTP is: 123456.

@www.example.com #123456

Voici quelques exemples à ne pas suivre:

Exemple de SMS incorrect Pourquoi cela ne fonctionne 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
Impossible d'inclure le schéma d'URL.
Your verification code is 123456

@https://example.com #123456
Impossible d'inclure le 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
Impossible d'inclure le chemin d'accès.
Your verification code is 123456

@example .com #123456
Le domaine ne contient aucun espace.
Your verification code is 123456

@domain-forbiden-chars-#%/:<>?@[] #123456
Le domaine ne comporte aucun caractère interdit.
@example.com #123456

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

App hash #oudf08lkjsdf834
@host et #code devraient ê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 le dupliquer et créer votre version : https://glitch.com/edit/#!/web-otp.

Utiliser WebOTP depuis un iFrame d'origine différente

La saisie d'un mot de passe à usage unique envoyé par SMS vers un iFrame multi-origine est généralement utilisé pour la confirmation du paiement, en particulier avec 3D Secure. L'API WebOTP utilise un format commun compatible avec les iFrames multi-origines pour diffuser les mots de passe à usage unique liés aux origines imbriquées. Exemple :

  • Un utilisateur accède à shop.example pour acheter une paire de chaussures avec une carte de crédit.
  • Une fois le numéro de carte de crédit saisi, le fournisseur de services 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 pouvoir payer rapidement.
  • bank.example envoie un SMS contenant un mot de passe à usage unique à l'utilisateur afin qu'il puisse le saisir et vérifier son identité.

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

  • Annotez l'origine du frame supérieur et l'origine de l'iFrame dans le SMS.
  • Configurez une règle d'autorisation pour permettre à l'iFrame multi-origine de recevoir directement l'OTP de l'utilisateur.
L'API WebOTP dans un iFrame en action.

Vous pouvez essayer la démonstration sur https://web-otp-iframe-demo.stackblitz.io.

Annoter les origines liées au SMS

Lorsque l'API WebOTP est appelée depuis un iFrame, le SMS doit inclure l'origine du cadre supérieur, précédé de @, suivi du mot de passe à usage unique précédé de #, et de l'origine de l'iFrame, précédé de @ sur la dernière ligne.

Your verification code is 123456

@shop.example #123456 @bank.exmple

Configurer la règle d'autorisation

Pour utiliser WebOTP dans un iFrame multi-origine, l'outil d'intégration doit accorder l'accès à cette API via la règle d'autorisation otp-credentials afin d'éviter tout comportement inattendu. En général, il existe deux façons d'atteindre cet objectif:

via l'en-tête HTTP:

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

via l'attribut iFrame allow:

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

Découvrez d'autres exemples sur la spécification d'une règle d'autorisation .

Utiliser WebOTP sur un ordinateur

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

API WebOTP sur ordinateur.

Cette fonctionnalité nécessite que l'utilisateur se connecte au même compte Google dans Chrome pour ordinateur et dans le navigateur Android.

Les développeurs n'ont qu'à implémenter l'API WebOTP sur leur site Web pour ordinateur de la même manière qu'ils le feraient sur leur site Web mobile. Aucune astuce particulière n'est requise.

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

Questions fréquentes

La boîte de dialogue ne s'affiche pas. J'envoie un message correctement formaté. Que se passe-t-il ?

Lorsque vous testez l'API, les mises en garde suivantes s'appliquent:

  • Si le numéro de téléphone de l'expéditeur est inclus dans la liste de contacts du destinataire, cette API ne se déclenchera pas 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 WebOTP ne fonctionne pas, essayez d'installer et d'utiliser Chrome sur votre profil personnel (c'est-à-dire le même profil que celui sur lequel vous recevez des SMS).

Vérifiez le format pour vous assurer que le format du SMS est correct.

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

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

L'utilisation de SMS comme moyen d'authentification est-elle sûre ?

Bien que l'OTP par SMS soit utile pour valider un numéro de téléphone lors de sa première utilisation, la validation par SMS doit être utilisée avec précaution pour la réauthentification, car les numéros de téléphone peuvent être piratés et recyclés par les opérateurs. WebOTP est un mécanisme de réauthentification et de récupération pratique, mais les services doivent l'associer à 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 des bugs d'implémentation dans Chrome ?

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

  • Signalez un bug à l'adresse https://new.crbug.com. Fournissez autant de détails que possible, indiquez des instructions simples pour reproduire le problème et définissez Composants sur Blink>WebOTP.

Comment puis-je améliorer cette fonctionnalité ?

Comptez-vous utiliser l'API WebOTP ? Votre assistance publique 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 avec le hashtag #WebOTP, et indiquez-nous où et comment vous l'utilisez.

Ressources