È comune chiedere a un utente di fornire una password monouso (OTP) per confermare la sua identità inviando un SMS. Alcuni casi d'uso per l'OTP via SMS includono:
- Autenticazione a due fattori. Oltre al nome utente e alla password, l'OTP via SMS può essere utilizzato come un forte indicatore del fatto che l'account appartiene alla persona che ha ricevuto l'OTP via SMS.
- Verifica del numero di telefono. Alcuni servizi utilizzano un numero di telefono come identificatore principale dell'utente. In questi servizi, gli utenti possono inserire il proprio numero di telefono e la OTP ricevuta tramite SMS per dimostrare la propria identità. A volte viene combinata con un PIN per costituire un'autenticazione a due fattori.
- Recupero dell'account. Quando un utente perde l'accesso al proprio account, deve esserci un modo per recuperarlo. L'invio di un'email all'indirizzo email registrato o di un OTP via SMS al numero di telefono sono metodi comuni di recupero dell'account.
- Conferma del pagamento Nei sistemi di pagamento, alcune banche o emittenti di carte di credito richiedono un'autenticazione aggiuntiva da parte del pagatore per motivi di sicurezza. La OTP via SMS è di uso comune a questo scopo.
Continua a leggere per scoprire le best practice per la creazione di moduli OTP via SMS per questi casi d'uso.
Elenco di controllo
Per offrire la migliore esperienza utente con l'OTP via SMS, segui questi passaggi:
- Utilizza l'elemento
<input>con:type="text"inputmode="numeric"autocomplete="one-time-code"
- Utilizza
@BOUND_DOMAIN #OTP_CODEcome ultima riga del messaggio SMS OTP. - Utilizza l'API WebOTP.
Utilizza l'elemento <input>
L'utilizzo di un modulo con un elemento <input> è la best practice più importante che puoi seguire perché funziona in tutti i browser. Anche se altri suggerimenti di questo post non funzionano in alcuni browser, l'utente potrà comunque inserire e inviare l'OTP manualmente.
<form action="/verify-otp" method="POST">
<input type="text"
inputmode="numeric"
autocomplete="one-time-code"
pattern="\d{6}"
required>
</form>
Di seguito sono riportate alcune idee per garantire che un campo di immissione sfrutti al meglio la funzionalità del browser.
type="text"
Poiché le OTP sono in genere numeri di cinque o sei cifre, l'utilizzo di type="number" per un campo di immissione potrebbe sembrare intuitivo perché cambia la tastiera mobile in soli numeri. Questa operazione non è consigliata perché il browser si aspetta che un campo di immissione sia un numero numerabile anziché una sequenza di più numeri, il che può causare un comportamento imprevisto. L'utilizzo di type="number" comporta la visualizzazione dei pulsanti Su e Giù accanto al campo di immissione. Se premi questi pulsanti, il numero aumenta o diminuisce e gli zeri precedenti potrebbero essere rimossi.
Usa invece il descrittore type="text". In questo modo, la tastiera mobile non verrà convertita solo in numeri, ma non è un problema perché il prossimo suggerimento per l'utilizzo di inputmode="numeric" svolge questa funzione.
inputmode="numeric"
Utilizza inputmode="numeric"
per passare alla tastiera numerica sul dispositivo mobile.
Alcuni siti web utilizzano type="tel" per i campi di immissione delle OTP, poiché quando è attivo,
trasforma anche la tastiera mobile in soli numeri (tra cui * e #). Questo hack è stato utilizzato in passato quando inputmode="numeric"
non era ampiamente supportato. Da quando Firefox ha iniziato a supportare
inputmode="numeric",
non è più necessario utilizzare l'hack type="tel" semanticamente errato.
autocomplete="one-time-code"
L'attributo autocomplete consente agli sviluppatori di specificare l'autorizzazione del browser per fornire assistenza per il completamento automatico e informa il browser sul tipo di informazioni previste nel campo.
Con autocomplete="one-time-code", ogni volta che un utente riceve un SMS mentre un modulo è aperto, il sistema operativo analizza l'OTP nell'SMS in modo euristico e la tastiera suggerisce l'OTP che l'utente deve inserire. Funziona solo su Safari 12 e versioni successive su iOS, iPadOS e macOS, ma ti consigliamo vivamente di utilizzarlo, perché è un modo migliore per migliorare l'esperienza con le OTP via SMS su queste piattaforme.
autocomplete="one-time-code" in azione.
autocomplete="one-time-code" migliora l'esperienza utente, ma puoi fare di più assicurandoti che il messaggio SMS sia conforme al formato del messaggio associato all'origine.
Attributi facoltativi
Gli attributi facoltativi includono:
patternspecifica il formato che deve corrispondere alla OTP inserita. Utilizza le espressioni regolari per specificare il pattern di corrispondenza. Ad esempio,\d{6}limita l'OTP a una stringa di sei cifre. Per saperne di più supattern, leggi Utilizza JavaScript per una convalida in tempo reale più complessa.requiredindica che un utente deve compilare il campo.
Per ulteriori consigli, leggi le nostre best practice per i moduli di accesso.
Formatta il testo dell'SMS
Migliora l'esperienza utente di inserimento di una OTP allineandoti alla specifica dei codici monouso associati all'origine inviati tramite SMS.
In sostanza, la regola di formato è la seguente: termina il messaggio SMS con il dominio del destinatario preceduto da @ e l'OTP preceduto da #.
Ad esempio:
Your OTP is 123456
@web-otp.example.com #123456
Il formato standard per i messaggi OTP semplifica l'estrazione e la rende più affidabile. L'associazione dei codici OTP ai siti web rende più difficile indurre gli utenti a fornire un codice a siti dannosi.
Regole di formattazione precise
Le regole precise sono:
- Il messaggio inizia con un testo leggibile (facoltativo) che contiene una stringa alfanumerica di 4-10 caratteri con almeno un numero, lasciando l'ultima riga per l'URL e l'OTP.
- La parte del dominio dell'URL del sito web che ha richiamato l'API deve essere preceduta da
@. - L'URL deve contenere un
#, seguito dalla OTP. Il numero di caratteri deve essere pari o inferiore a 140.
L'utilizzo di questo formato offre un paio di vantaggi:
- La OTP sarà associata al dominio. Se l'utente si trova su domini diversi da quello specificato nel messaggio SMS, il suggerimento OTP non verrà visualizzato. In questo modo si riduce anche il rischio di attacchi di phishing e di potenziali compromissioni dell'account.
- Il browser sarà ora in grado di estrarre in modo affidabile l'OTP senza dipendere da euristiche misteriose e instabili.
Quando un sito web utilizza autocomplete="one-time-code", Safari con iOS 14 o versioni successive suggerirà l'OTP seguendo queste regole.
Questo formato dei messaggi SMS è utile anche per i browser diversi da Safari. Anche Chrome, Opera e Vivaldi su Android supportano la regola dei codici monouso associati all'origine con l'API WebOTP, anche se non tramite autocomplete="one-time-code".
Utilizza l'API WebOTP
L'API WebOTP fornisce l'accesso all'OTP ricevuto in un messaggio SMS. Chiamando
navigator.credentials.get()
con il tipo otp (OTPCredential) dove transport include sms, il sito web
attenderà la consegna di un SMS conforme ai codici monouso associati all'origine e
l'accesso da parte dell'utente. Una volta che l'OTP viene passato a JavaScript, il sito web può utilizzarlo in un modulo o inviarlo direttamente al server tramite POST.
navigator.credentials.get({
otp: {transport:['sms']}
})
.then(otp => input.value = otp.code);
Scopri come utilizzare l'API WebOTP in dettaglio in Verifica i numeri di telefono sul web con l'API WebOTP o copia e incolla lo snippet seguente. Assicurati di impostare un attributo action e method nel tuo <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);
});
});
}