Verifica i numeri di telefono sul web con l'API WebOTP

Aiuta gli utenti con OTP ricevute tramite SMS

Eiji Kitamura
Eiji Kitamura

Che cos'è l'API WebOTP?

Oggigiorno, la maggior parte delle persone al mondo possiede un dispositivo mobile e gli sviluppatori utilizzano di solito i numeri di telefono come identificatore degli utenti dei loro servizi.

Esistono diversi modi per verificare i numeri di telefono, ma una delle password unica generate in modo casuale (OTP) inviata tramite SMS è uno dei più comuni. L'invio di questo codice al server dello sviluppatore dimostra il controllo del numero di telefono.

Questa idea è già stata implementata in molti scenari per:

  • Numero di telefono come identificatore dell'utente. Durante la registrazione a un nuovo servizio, alcuni siti web chiedono un numero di telefono anziché un indirizzo email e lo utilizzano come identificatore dell'account.
  • Verifica in due passaggi. Quando si accede, un sito web richiede un codice una tantum inviato tramite SMS in aggiunta a una password o a un altro fattore di conoscenza per una maggiore sicurezza.
  • Conferma di pagamento. Quando un utente effettua un pagamento, la richiesta di un codice monouso inviato tramite SMS può aiutare a verificare l'intenzione della persona.

La procedura attuale crea problemi per gli utenti. Trovare una OTP all'interno di un messaggio SMS e poi copiarla e incollarla nel modulo è un'operazione complessa che riduce i tassi di conversione nei percorsi degli utenti critici. E questo è stato per molto tempo una richiesta del web da parte di molti dei più grandi sviluppatori mondiali. Android dispone di un'API che fa esattamente questo. Anche iOS e Safari.

L'API WebOTP consente alla tua app di ricevere messaggi con formati speciali associati al dominio dell'app. Da qui, puoi ottenere in modo programmatico una OTP da un messaggio SMS e verificare più facilmente un numero di telefono per l'utente.

Guarda come funziona

Supponiamo che un utente voglia verificare il proprio numero di telefono con un sito web. Il sito web invia un messaggio di testo all'utente tramite SMS e l'utente inserisce l'OTP dal messaggio per verificare la proprietà del numero di telefono.

Con l'API WebOTP, questi passaggi sono semplici come un tocco per l'utente, come mostrato nel video. Quando arriva l'SMS, viene visualizzato un riquadro inferiore che chiede all'utente di verificare il proprio numero di telefono. Dopo aver fatto clic sul pulsante Verifica nel riquadro inferiore, il browser incolla l'OTP nel modulo e il modulo viene inviato senza che l'utente debba premere Continua.

L'intero processo è illustrato in un diagramma nell'immagine seguente.

Diagramma dell'API WebOTP

Prova anche tu la demo. Non ti viene richiesto il numero di telefono e non viene inviato un SMS al dispositivo, ma puoi inviare un SMS da un altro dispositivo copiando il testo visualizzato nella demo. Questo funziona perché non importa chi sia il mittente quando utilizzi l'API WebOTP.

  1. Vai alla pagina https://web-otp.glitch.me in Chrome 84 o versioni successive su un dispositivo Android.
  2. Invia al tuo smartphone il seguente SMS da un altro telefono.
Your OTP is: 123456.

@web-otp.glitch.me #12345

Hai ricevuto l'SMS e ti è stato chiesto di inserire il codice nell'area di immissione? Ecco come funziona l'API WebOTP per gli utenti.

L'utilizzo dell'API WebOTP è costituito da tre parti:

  • Un tag <input> annotato correttamente
  • JavaScript nella tua applicazione web
  • Testo del messaggio formattato inviato tramite SMS.

Innanzitutto, parlerò del tag <input>.

Annota un tag <input>

WebOTP funziona senza alcuna annotazione HTML, ma per la compatibilità tra browser, ti consiglio vivamente di aggiungere autocomplete="one-time-code" al tag <input> nel punto in cui prevedi che l'utente inserisca una OTP.

In questo modo Safari 14 o versioni successive può suggerire all'utente di compilare automaticamente il campo <input> con una OTP quando riceve un SMS con il formato descritto in Formattare il messaggio SMS, anche se non supporta WebOTP.

HTML

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

Utilizzare l'API WebOTP

Poiché WebOTP è semplice, è sufficiente copiare e incollare il seguente codice. Comunque, ti spiegherò cosa sta succedendo.

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);
    });
  });
}

Rilevamento delle funzionalità

Il rilevamento delle funzionalità è uguale a quello di molte altre API. In ascolto dell'evento DOMContentLoaded attenderà che la struttura DOM sia pronta per la query.

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');
    …
  });
}

Elabora l'OTP

L'API WebOTP è sufficientemente semplice. Utilizza navigator.credentials.get() per ottenere l'OTP. WebOTP aggiunge una nuova opzione otp a questo metodo. Ha una sola proprietà, transport, il cui valore deve essere un array con la stringa 'sms'.

JavaScript

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

In questo modo viene attivato il flusso di autorizzazione del browser all'arrivo di un SMS. Se viene concessa l'autorizzazione, la promessa restituita viene risolta con un oggetto OTPCredential.

Contenuto dell'oggetto OTPCredential ottenuto

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

Quindi, passa il valore OTP al campo <input>. L'invio diretto del modulo elimina il passaggio che richiede all'utente di toccare un pulsante.

JavaScript

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

Interruzione del messaggio

Se l'utente inserisce manualmente una OTP e invia il modulo, puoi annullare la chiamata get() utilizzando un'istanza AbortController nell'oggetto 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 => {
    …

Formattare l'SMS

L'API dovrebbe apparire abbastanza semplice, ma ci sono alcune cose che dovresti sapere prima di utilizzarla. Il messaggio deve essere inviato dopo la chiamata a navigator.credentials.get() e deve essere ricevuto sul dispositivo su cui è stata chiamata get(). Infine, il messaggio deve rispettare la seguente formattazione:

  • Il messaggio inizia con un testo leggibile (facoltativo) contenente una stringa alfanumerica di quattro-dieci caratteri e almeno un numero a partire dall'ultima riga dell'URL e dell'OTP.
  • La parte del dominio dell'URL del sito web che ha richiamato l'API deve essere preceduta da @.
  • L'URL deve contenere un simbolo di cancelletto ("#") seguito dalla OTP.

Ad esempio:

Your OTP is: 123456.

@www.example.com #123456

Ecco alcuni esempi errati:

Esempio di testo SMS non corretto Perché non funzionerà
Here is your code for @example.com #123456 @ deve essere il primo carattere dell'ultima riga.
Your code for @example.com is #123456 @ deve essere il primo carattere dell'ultima riga.
Your verification code is 123456

@example.com\t#123456
È previsto un singolo spazio tra le date @host e #code.
Your verification code is 123456

@example.com  #123456
È previsto un singolo spazio tra le date @host e #code.
Your verification code is 123456

@ftp://example.com #123456
Lo schema URL non può essere incluso.
Your verification code is 123456

@https://example.com #123456
Lo schema URL non può essere incluso.
Your verification code is 123456

@example.com:8080 #123456
Non è possibile includere la porta.
Your verification code is 123456

@example.com/foobar #123456
Impossibile includere il percorso.
Your verification code is 123456

@example .com #123456
Nessuno spazio vuoto nel dominio.
Your verification code is 123456

@domain-forbiden-chars-#%/:<>?@[] #123456
Nessun caratteri non consentiti nel dominio.
@example.com #123456

Mambo Jumbo
@host e #code dovrebbero essere l'ultima riga.
@example.com #123456

App hash #oudf08lkjsdf834
@host e #code dovrebbero essere l'ultima riga.
Your verification code is 123456

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

example.com #123456
@ mancante.
Hi mom, did you receive my last text @ e # mancanti.

Demo

Prova vari messaggi con la demo: https://web-otp.glitch.me

Puoi anche creare un fork e creare la tua versione: https://glitch.com/edit/#!/web-otp.

Utilizza WebOTP da un iframe multiorigine

L'inserimento di una OTP SMS in un iframe multiorigine viene in genere utilizzato per la conferma del pagamento, in particolare con 3D Secure. Avendo il formato comune per supportare iframe multiorigine, l'API WebOTP offre OTP associate a origini nidificate. Ad esempio:

  • Un utente visita shop.example per acquistare un paio di scarpe con una carta di credito.
  • Dopo aver inserito il numero della carta di credito, il fornitore di servizi di pagamento integrato mostra un modulo di bank.example all'interno di un iframe in cui viene chiesto all'utente di verificare il numero di telefono per il pagamento rapido.
  • bank.example invia un SMS contenente una OTP all'utente in modo che possa inserirlo per verificare la propria identità.

Per utilizzare l'API WebOTP dall'interno di un iframe multiorigine, devi eseguire due operazioni:

  • Annota sia l'origine del frame superiore che l'origine dell'iframe nell'SMS.
  • Configura il criterio di autorizzazione per consentire all'iframe multiorigine di ricevere OTP direttamente dall'utente.
API WebOTP all'interno di un iframe in azione.

Puoi provare la demo all'indirizzo https://web-otp-iframe-demo.stackblitz.io.

Annota le origini associate nel messaggio di testo SMS

Quando l'API WebOTP viene chiamata dall'interno di un iframe, l'SMS deve includere l'origine del frame superiore preceduta da @ seguita dalla OTP preceduta da # e l'origine dell'iframe preceduta da @ nell'ultima riga.

Your verification code is 123456

@shop.example #123456 @bank.exmple

Configura criterio di autorizzazione

Per utilizzare WebOTP in un iframe multiorigine, l'incorporamento deve concedere l'accesso a questa API tramite i criteri di autorizzazione otp-credentials per evitare comportamenti indesiderati. In generale, esistono due modi per raggiungere questo obiettivo:

tramite intestazione HTTP:

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

tramite l'attributo iframe allow:

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

Guarda altri esempi su come specificare un criterio di autorizzazione .

Utilizzare WebOTP su computer

In Chrome, WebOTP supporta l'ascolto degli SMS ricevuti su altri dispositivi per aiutare gli utenti a completare la verifica del numero di telefono su computer.

API WebOTP su computer.

Questa funzionalità richiede che l'utente acceda allo stesso Account Google su Chrome per computer desktop e Chrome per Android.

Tutti gli sviluppatori devono implementare l'API WebOTP sul loro sito web desktop, nello stesso modo in cui lo fanno sul loro sito web mobile, ma non sono necessari trucchetti speciali.

Per ulteriori informazioni, vedi Verificare un numero di telefono su computer utilizzando l'API WebOTP.

Domande frequenti

La finestra di dialogo non viene visualizzata anche se sto inviando un messaggio formattato correttamente. Che sta succedendo?

Durante il test dell'API occorre tenere presenti i seguenti aspetti:

  • Se il numero di telefono del mittente è incluso nell'elenco contatti del destinatario, questa API non viene attivata a causa della progettazione dell'API SMS User Consent sottostante.
  • Se utilizzi un profilo di lavoro sul tuo dispositivo Android e il WebOTP non funziona, prova a installare e utilizzare Chrome sul tuo profilo personale (ovvero lo stesso profilo in cui ricevi SMS).

Ricontrolla il formato per verificare che il formato dell'SMS sia corretto.

Questa API è compatibile con diversi browser?

Chromium e WebKit si sono accordati sul formato SMS e Apple ha annunciato il supporto di Safari a partire da iOS 14 e macOS Big Sur. Sebbene Safari non supporti l'API WebOTP JavaScript, annotando l'elemento input con autocomplete=["one-time-code"], la tastiera predefinita ti suggerisce automaticamente di inserire l'OTP se il messaggio SMS è conforme al formato.

È sicuro utilizzare gli SMS come metodo di autenticazione?

L'OTP SMS è utile per verificare un numero di telefono quando il numero viene fornito per la prima volta, ma la verifica del numero di telefono tramite SMS deve essere utilizzata con cautela per la riautenticazione, poiché i numeri di telefono possono essere compromessi e riciclati dagli operatori. WebOTP è un comodo meccanismo di riautenticazione e recupero, ma i servizi dovrebbero combinarlo con fattori aggiuntivi, come una verifica delle conoscenze, oppure utilizzare l'API Web Authentication per un'autenticazione avanzata.

Dove posso segnalare bug nell'implementazione di Chrome?

Hai trovato un bug nell'implementazione di Chrome?

  • Segnala un bug all'indirizzo https://new.crbug.com. Includi il maggior numero possibile di dettagli, semplici istruzioni per la riproduzione e imposta Componenti su Blink>WebOTP.

Come posso aiutare questa funzionalità?

Hai intenzione di utilizzare l'API WebOTP? Il tuo supporto pubblico ci aiuta a stabilire le priorità delle funzionalità e mostra ad altri fornitori di browser l'importanza di supportarle. Invia un tweet a @ChromiumDev usando l'hashtag #WebOTP e facci sapere dove e come lo utilizzi.

Risorse