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 code OTP par SMS peut être utilisé comme signal fort indiquant que le compte appartient à la personne qui a reçu le code OTP par SMS.
- Validation 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 code secret à usage unique reçu par SMS pour prouver leur identité. Il est parfois associé à un code secret pour constituer une authentification à deux facteurs.
- Récupération de compte : Lorsqu'un utilisateur perd l'accès à son compte, il doit pouvoir le récupérer. L'envoi d'un e-mail à leur adresse e-mail enregistrée ou d'un code OTP par SMS à leur numéro de téléphone sont des méthodes courantes de récupération de compte.
- Confirmation du paiement : dans les systèmes de paiement, certaines banques ou certains émetteurs de cartes de crédit demandent une authentification supplémentaire du payeur pour des raisons de sécurité. Les codes secrets à usage unique par SMS sont généralement utilisés à cette fin.
Poursuivez votre lecture pour découvrir les bonnes pratiques concernant la création de formulaires de code OTP par SMS pour ces cas d'utilisation.
Checklist
Pour offrir la meilleure expérience utilisateur possible avec le code secret unique par SMS, suivez ces étapes :
- Utilisez l'élément
<input>
avec :type="text"
inputmode="numeric"
autocomplete="one-time-code"
- Utilisez
@BOUND_DOMAIN #OTP_CODE
comme dernière ligne du message SMS contenant le code secret à 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 à suivre, car elle fonctionne dans tous les navigateurs. Même si d'autres suggestions de ce post ne fonctionnent pas dans certains navigateurs, l'utilisateur pourra toujours saisir et envoyer le code OTP 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 tirer le meilleur parti des fonctionnalités du navigateur dans un champ de saisie.
type="text"
Comme les codes secrets à usage unique 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 approche 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 des boutons haut et bas à côté du champ de saisie. Appuyer sur ces boutons augmente ou diminue 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 uniquement, mais ce n'est pas grave, car le prochain conseil pour utiliser inputmode="numeric"
le fera.
inputmode="numeric"
Utilisez inputmode="numeric"
pour afficher uniquement des chiffres sur le clavier mobile.
Certains sites Web utilisent type="tel"
pour les champs de saisie de code secret à usage unique, car cela permet également de passer le clavier mobile en mode numérique uniquement (y compris *
et #
) lorsque le champ est sélectionné. Cette astuce était utilisée dans le passé lorsque inputmode="numeric"
n'était pas largement pris en charge. Étant donné que Firefox est désormais compatible avec inputmode="numeric"
, il n'est plus nécessaire d'utiliser le hack type="tel"
sémantiquement incorrect.
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 sur le type d'informations attendues dans le champ.
Avec autocomplete="one-time-code"
, chaque fois qu'un utilisateur reçoit un message 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'utilisateur de le saisir. Il ne fonctionne que sur Safari 12 et versions ultérieures sur iOS, iPadOS et macOS, mais nous vous recommandons vivement de l'utiliser, car il permet d'améliorer l'expérience des codes secrets à usage unique 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 faire plus en vous assurant que le message SMS respecte le format des messages liés à l'origine.
Attributs facultatifs
Voici quelques exemples d'attributs facultatifs :
pattern
spécifie le format auquel le code secret à usage unique saisi doit correspondre. Utilisez des expressions régulières pour spécifier le modèle de correspondance. Par exemple,\d{6}
contraint le code secret à une chaîne de six chiffres. Pour en savoir plus surpattern
, consultez Utiliser JavaScript pour une validation en temps réel plus complexe.required
indique qu'un 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 code secret à usage unique en vous conformant à la spécification des codes secrets à usage unique liés à l'origine et envoyés par SMS.
La règle de format de base est la suivante : terminez le message SMS par le domaine du destinataire précédé de @
et le code OTP précédé de #
.
Exemple :
Your OTP is 123456
@web-otp.glitch.me #123456
Le format standard des messages OTP facilite l'extraction et la rend plus fiable. Associer les codes OTP à des sites Web permet d'empêcher plus facilement les utilisateurs de fournir un code à des sites malveillants.
Règles de mise en forme précises
Voici les règles précises :
- Le message commence par un texte lisible par un humain (facultatif) qui contient une chaîne alphanumérique de quatre à dix caractères avec au moins un chiffre, la dernière ligne étant réservée à l'URL et au 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
#
, suivi du code secret à usage unique. Le nombre de caractères doit être inférieur ou égal à 140.
L'utilisation de ce format présente plusieurs avantages :
- L'OTP sera lié au domaine. Si l'utilisateur se trouve sur un domaine autre que celui spécifié dans le message SMS, la suggestion de code secret à usage unique ne s'affiche pas. Cela permet également de réduire le risque d'attaques par hameçonnage et de piratage de compte.
- Le navigateur pourra désormais extraire l'OTP 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 code secret à usage unique en suivant ces règles.
Ce format de message SMS est également avantageux pour les navigateurs autres que Safari. Chrome, Opera et Vivaldi sur Android sont également compatibles avec la règle des codes secrets à 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 code OTP reçu dans un message SMS. En appelant navigator.credentials.get()
avec le type otp
(OTPCredential
) où transport
inclut sms
, le site Web attendra qu'un SMS conforme aux mots de passe à usage unique liés à l'origine soit envoyé et que l'utilisateur accorde l'accès. Une fois le code OTP transmis à JavaScript, le site Web peut l'utiliser dans un formulaire ou l'envoyer directement au serveur.
navigator.credentials.get({
otp: {transport:['sms']}
})
.then(otp => input.value = otp.code);
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 suivant. Veillez à définir les attributs 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);
});
});
}