Bonnes pratiques concernant les formulaires OTP envoyés par SMS

Il est courant de demander à un utilisateur de fournir un mot de passe à usage unique (OTP) pour confirmer son identité en envoyant un SMS. Voici quelques cas d'utilisation des OTP par SMS :

  • Authentification à deux facteurs En plus du nom d'utilisateur et du mot de passe, le mot de passe à usage unique par SMS peut être utilisé comme un signal fort indiquant que le compte appartient à la personne qui a reçu le mot de passe à usage unique par SMS.
  • Vérification du numéro de téléphone Certains services utilisent un numéro de téléphone comme identifiant principal de l'utilisateur. Dans ces services, les utilisateurs peuvent saisir leur numéro de téléphone et le mot de passe à usage unique reçu par SMS pour prouver leur identité. Elle est parfois combinée à un code pour constituer une authentification à deux facteurs.
  • Récupération de compte Lorsqu'un utilisateur perd l'accès à son compte, il doit exister un moyen de le récupérer. L'envoi d'un e-mail à l'adresse e-mail enregistrée ou d'un OTP par SMS au numéro de téléphone sont des méthodes courantes de récupération de compte.
  • Confirmation de paiement : dans les systèmes de paiement, certaines banques ou certains émetteurs de cartes de crédit demandent une authentification supplémentaire au payeur pour des raisons de sécurité. Les mots de passe à usage unique par SMS sont couramment utilisés à cette fin.

Poursuivez votre lecture pour découvrir les bonnes pratiques à suivre pour créer des formulaires de mot de passe à usage unique par SMS pour ces cas d'utilisation.

Checklist

Pour offrir la meilleure expérience utilisateur possible avec le mot de passe à usage unique par SMS, procédez comme suit :

  • Utilisez l'élément <input> avec :
    • type="text"
    • inputmode="numeric"
    • autocomplete="one-time-code"
  • Utilisez @BOUND_DOMAIN #OTP_CODE comme dernière ligne du SMS contenant le mot de passe à usage unique.
  • Utilisez l'API WebOTP.

Utiliser l'élément <input>

L'utilisation d'un formulaire avec un élément <input> est la bonne pratique la plus importante que vous puissiez suivre, car elle fonctionne dans tous les navigateurs. Même si les autres suggestions de cet article ne fonctionnent pas dans certains navigateurs, l'utilisateur pourra toujours saisir et envoyer le mot de passe à usage unique manuellement.

<form action="/verify-otp" method="POST">
  <input type="text"
      inputmode="numeric"
      autocomplete="one-time-code"
      pattern="\d{6}"
      required>
</form>

Voici quelques idées pour vous assurer qu'un champ de saisie tire le meilleur parti des fonctionnalités du navigateur.

type="text"

Comme les OTP sont généralement des nombres à cinq ou six chiffres, l'utilisation de type="number" pour un champ de saisie peut sembler intuitive, car elle permet de passer au clavier numérique sur mobile. Cette pratique n'est pas recommandée, car le navigateur s'attend à ce qu'un champ de saisie soit un nombre dénombrable plutôt qu'une séquence de plusieurs nombres, ce qui peut entraîner un comportement inattendu. L'utilisation de type="number" entraîne l'affichage de boutons vers le haut et vers le bas à côté du champ de saisie. Appuyer sur ces boutons incrémente ou décrémente le nombre et peut supprimer les zéros précédents.

Utilisez type="text" à la place. Cela ne transformera pas le clavier mobile en clavier numérique, mais ce n'est pas un problème, car l'astuce suivante pour utiliser inputmode="numeric" s'en chargera.

inputmode="numeric"

Utilisez inputmode="numeric" pour que le clavier mobile n'affiche que des chiffres.

Certains sites Web utilisent type="tel" pour les champs de saisie de l'OTP, car il permet également de basculer le clavier mobile sur les chiffres uniquement (y compris * et #) lorsqu'il est sélectionné. Cette astuce était utilisée par le passé, lorsque inputmode="numeric" n'était pas largement pris en charge. Depuis que Firefox est compatible avec inputmode="numeric", il n'est plus nécessaire d'utiliser l'astuce type="tel", qui est sémantiquement incorrecte.

autocomplete="one-time-code"

L'attribut autocomplete permet aux développeurs de spécifier l'autorisation dont dispose le navigateur pour fournir une assistance à la saisie semi-automatique et informe le navigateur du type d'informations attendues dans le champ.

Avec autocomplete="one-time-code", chaque fois qu'un utilisateur reçoit un SMS alors qu'un formulaire est ouvert, le système d'exploitation analyse l'OTP dans le SMS de manière heuristique, et le clavier suggère l'OTP à l'utilisateur. Elle ne fonctionne que sur Safari 12 et versions ultérieures sur iOS, iPadOS et macOS, mais nous vous recommandons vivement de l'utiliser, car elle permet d'améliorer l'expérience des OTP par SMS sur ces plates-formes.

autocomplete="one-time-code" en action.

autocomplete="one-time-code" améliore l'expérience utilisateur, mais vous pouvez aller plus loin en vous assurant que le message SMS est conforme au format de message lié à l'origine.

Attributs facultatifs

Les attributs facultatifs sont les suivants :

  • pattern spécifie le format auquel le mot de passe à usage unique saisi doit correspondre. Utilisez des expressions régulières pour spécifier le format de correspondance. Par exemple, \d{6} limite le mot de passe à usage unique à une chaîne de six chiffres. Pour en savoir plus sur pattern, consultez Utiliser JavaScript pour une validation en temps réel plus complexe.
  • required indique que l'utilisateur doit remplir le champ.

Pour obtenir d'autres conseils, consultez nos bonnes pratiques concernant les formulaires de connexion.

Mettre en forme le texte du SMS

Améliorez l'expérience utilisateur lors de la saisie d'un OTP en vous alignant sur la spécification des codes à usage unique liés à l'origine envoyés par SMS.

La règle de format est la suivante : terminez le SMS par le domaine du destinataire précédé de @, et le mot de passe à usage unique précédé de #.

Exemple :

Your OTP is 123456

@web-otp.example.com #123456

Le format standard des messages OTP facilite l'extraction et la rend plus fiable. Associer des codes OTP à des sites Web permet d'éviter que les utilisateurs ne fournissent un code à des sites malveillants.

Règles de mise en forme précises

Les règles précises sont les suivantes :

  • Le message commence par un texte lisible par l'humain (facultatif) contenant 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 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 #, suivi du mot de passe à usage unique. Le nombre de caractères ne doit pas dépasser 140.

L'utilisation de ce format présente plusieurs avantages :

  • Le mot de passe à usage unique sera lié au domaine. Si l'utilisateur se trouve sur des domaines autres que celui spécifié dans le SMS, la suggestion de mot de passe à usage unique ne s'affiche pas. Cela réduit également le risque d'attaques par hameçonnage et de piratage de compte.
  • Le navigateur pourra désormais extraire le mot de passe à usage unique de manière fiable, sans dépendre d'heuristiques mystérieuses et instables.

Lorsqu'un site Web utilise autocomplete="one-time-code", Safari avec iOS 14 ou version ultérieure suggère le mot de passe à usage unique en suivant ces règles.

Ce format de message SMS est également utile pour les navigateurs autres que Safari. Chrome, Opera et Vivaldi sur Android sont également compatibles avec la règle des codes à usage unique liés à l'origine avec l'API WebOTP, mais pas via autocomplete="one-time-code".

Utiliser l'API WebOTP

L'API WebOTP permet d'accéder au mot de passe à usage unique reçu dans un SMS. En appelant navigator.credentials.get() avec le type otp (OTPCredential) où transport inclut sms, le site Web attend qu'un SMS conforme aux codes uniques liés à l'origine soit envoyé et que l'utilisateur accorde l'accès. Une fois le mot de passe à usage unique transmis à JavaScript, le site Web peut l'utiliser dans un formulaire ou l'envoyer directement au serveur via une requête POST.

navigator.credentials.get({
  otp: {transport:['sms']}
})
.then(otp => input.value = otp.code);
API WebOTP en action.

Pour en savoir plus sur l'utilisation de l'API WebOTP, consultez Valider des numéros de téléphone sur le Web avec l'API WebOTP ou copiez et collez l'extrait de code suivant. Veillez à définir un attribut action et method dans votre <form>.

// Feature detection
if ('OTPCredential' in window) {
  window.addEventListener('DOMContentLoaded', e => {
    const input = document.querySelector('input[autocomplete="one-time-code"]');
    if (!input) return;
    // Cancel the WebOTP API if the form is submitted manually.
    const ac = new AbortController();
    const form = input.closest('form');
    if (form) {
      form.addEventListener('submit', e => {
        // Cancel the WebOTP API.
        ac.abort();
      });
    }
    // Invoke the WebOTP API
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
      input.value = otp.code;
      // Automatically submit the form when an OTP is obtained.
      if (form) form.submit();
    }).catch(err => {
      console.log(err);
    });
  });
}