Verifieer telefoonnummers op internet met de WebOTP API

Help gebruikers met OTP's ontvangen via sms

Wat is de WebOTP-API?

Tegenwoordig bezitten de meeste mensen ter wereld een mobiel apparaat en gebruiken ontwikkelaars vaak telefoonnummers als identificatie voor gebruikers van hun diensten.

Er zijn verschillende manieren om telefoonnummers te verifiëren, maar een willekeurig gegenereerd eenmalig wachtwoord (OTP) dat per sms wordt verzonden, is een van de meest voorkomende. Als u deze code terugstuurt naar de server van de ontwikkelaar, wordt de controle over het telefoonnummer gedemonstreerd.

Dit idee wordt al in veel scenario’s ingezet om het volgende te bereiken:

  • Telefoonnummer als identificatie voor de gebruiker. Wanneer u zich aanmeldt voor een nieuwe dienst, vragen sommige websites om een ​​telefoonnummer in plaats van een e-mailadres en gebruiken dit als accountidentificatie.
  • Tweestapsverificatie. Bij het inloggen vraagt ​​een website om een ​​eenmalige code die via sms wordt verzonden, naast een wachtwoord of andere kennisfactor voor extra veiligheid.
  • Betalingsbevestiging. Wanneer een gebruiker een betaling doet, kan het vragen om een ​​eenmalige code die via sms wordt verzonden, helpen de bedoeling van de persoon te verifiëren.

Het huidige proces zorgt voor wrijving bij gebruikers. Het vinden van een OTP in een sms-bericht en het vervolgens kopiëren en plakken in het formulier is omslachtig, waardoor de conversiepercentages in kritieke gebruikerstrajecten worden verlaagd. Dit versoepelen is al lang een verzoek aan het internet van veel van de grootste wereldwijde ontwikkelaars. Android heeft een API die precies dit doet . Hetzelfde geldt voor iOS en Safari .

Met de WebOTP API kan uw app speciaal opgemaakte berichten ontvangen die zijn gekoppeld aan het domein van uw app. Hieruit kunt u programmatisch een OTP uit een sms-bericht verkrijgen en gemakkelijker een telefoonnummer voor de gebruiker verifiëren.

Zie het in actie

Stel dat een gebruiker zijn telefoonnummer wil verifiëren bij een website. De website stuurt via sms een sms-bericht naar de gebruiker en de gebruiker voert het OTP uit het bericht in om de eigendom van het telefoonnummer te verifiëren.

Met de WebOTP API zijn deze stappen voor de gebruiker net zo eenvoudig als één tik, zoals gedemonstreerd in de video. Wanneer het sms-bericht binnenkomt, verschijnt er een onderste blad waarin de gebruiker wordt gevraagd zijn telefoonnummer te verifiëren. Nadat u op de knop Verifiëren op het onderste blad hebt geklikt, plakt de browser de OTP in het formulier en wordt het formulier verzonden zonder dat de gebruiker op Doorgaan hoeft te drukken.

Het hele proces is schematisch weergegeven in de onderstaande afbeelding.

WebOTP API-diagram

Probeer de demo zelf. Er wordt niet om uw telefoonnummer gevraagd en er wordt geen sms naar uw apparaat verzonden, maar u kunt er een vanaf een ander apparaat verzenden door de tekst te kopiëren die in de demo wordt weergegeven. Dit werkt omdat het niet uitmaakt wie de afzender is bij gebruik van de WebOTP API.

  1. Ga naar https://web-otp.glitch.me in Chrome 84 of hoger op een Android-apparaat.
  2. Stuur uw telefoon het volgende sms-bericht vanaf de andere telefoon.
Your OTP is: 123456.

@web-otp.glitch.me #12345

Heeft u de sms ontvangen en ziet u de prompt om de code in het invoerveld in te voeren? Zo werkt de WebOTP API voor gebruikers.

Het gebruik van de WebOTP API bestaat uit drie delen:

  • Een correct geannoteerde <input> -tag
  • JavaScript in uw webapp
  • Geformatteerde berichttekst verzonden via sms.

Ik zal eerst de <input> -tag behandelen.

Annoteer een <input> -tag

WebOTP zelf werkt zonder enige HTML-annotatie, maar voor compatibiliteit tussen browsers raad ik u ten zeerste aan autocomplete="one-time-code" toe te voegen aan de <input> -tag waar u verwacht dat de gebruiker een OTP invoert.

Hierdoor kan Safari 14 of hoger voorstellen dat de gebruiker het <input> -veld automatisch invult met een OTP wanneer hij een sms ontvangt met de indeling die wordt beschreven in Het sms-bericht formatteren, ook al wordt WebOTP niet ondersteund.

HTML

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

Gebruik de WebOTP-API

Omdat WebOTP eenvoudig is, volstaat het kopiëren en plakken van de volgende code. Ik zal je hoe dan ook laten zien wat er gebeurt.

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

Functiedetectie

Functiedetectie is hetzelfde als voor veel andere API's. Bij het luisteren naar de DOMContentLoaded gebeurtenis wordt gewacht totdat de DOM-structuur gereed is voor het uitvoeren van query's.

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

Verwerk het OTP

De WebOTP API zelf is eenvoudig genoeg. Gebruik navigator.credentials.get() om de OTP te verkrijgen. WebOTP voegt een nieuwe otp optie toe aan die methode. Het heeft slechts één eigenschap: transport , waarvan de waarde een array moet zijn met de string 'sms' .

JavaScript

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

Dit activeert de toestemmingsstroom van de browser wanneer een sms-bericht binnenkomt. Als toestemming wordt verleend, wordt de geretourneerde belofte opgelost met een OTPCredential object.

Inhoud van verkregen OTPCredential -object

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

Geef vervolgens de OTP-waarde door aan het veld <input> . Als u het formulier rechtstreeks indient, hoeft u niet meer op een knop te tikken.

JavaScript

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

Het bericht afbreken

Als de gebruiker handmatig een OTP invoert en het formulier verzendt, kunt u de get() aanroep annuleren door een AbortController instantie in het options object te gebruiken.

JavaScript

    …
    const ac = new AbortController();
    …
    if (form) {
      form.addEventListener('submit', e => {
        ac.abort();
      });
    }
    …
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
    …

Formatteer het SMS-bericht

De API zelf moet er eenvoudig genoeg uitzien, maar er zijn een paar dingen die u moet weten voordat u deze gebruikt. Het bericht moet worden verzonden nadat navigator.credentials.get() is aangeroepen en moet worden ontvangen op het apparaat waarop get() is aangeroepen. Ten slotte moet het bericht de volgende opmaak hebben:

  • Het bericht begint met (optionele) voor mensen leesbare tekst die een alfanumerieke reeks van vier tot tien tekens bevat, waarbij ten minste één nummer de laatste regel voor de URL en het OTP verlaat.
  • Het domeingedeelte van de URL van de website die de API heeft aangeroepen, moet worden voorafgegaan door @ .
  • De URL moet een hekje (' # ') bevatten, gevolgd door het OTP.

Bijvoorbeeld:

Your OTP is: 123456.

@www.example.com #123456

Hier zijn slechte voorbeelden:

Voorbeeld van verkeerd opgemaakte sms-tekst Waarom dit niet zal werken
Here is your code for @example.com #123456 @ is naar verwachting het eerste teken van de laatste regel.
Your code for @example.com is #123456 @ is naar verwachting het eerste teken van de laatste regel.
Your verification code is 123456

@example.com\t#123456
Er wordt een enkele spatie verwacht tussen @host en #code .
Your verification code is 123456

@example.com    #123456
Er wordt een enkele spatie verwacht tussen @host en #code .
Your verification code is 123456

@ftp://example.com #123456
URL-schema kan niet worden opgenomen.
Your verification code is 123456

@https://example.com #123456
URL-schema kan niet worden opgenomen.
Your verification code is 123456

@example.com:8080 #123456
Poort kan niet worden opgenomen.
Your verification code is 123456

@example.com/foobar #123456
Pad kan niet worden opgenomen.
Your verification code is 123456

@example .com #123456
Geen witruimte in domein.
Your verification code is 123456

@domain-forbiden-chars-#%/:<>?@[] #123456
Geen verboden tekens in domein.
@example.com #123456

Mambo Jumbo
@host en #code zijn naar verwachting de laatste regel.
@example.com #123456

App hash #oudf08lkjsdf834
@host en #code zijn naar verwachting de laatste regel.
Your verification code is 123456

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

example.com #123456
Missend @ .
Hi mom, did you receive my last text Ontbrekende @ en # .

Demo's

Probeer verschillende berichten met de demo: https://web-otp.glitch.me

Je kunt het ook forken en je eigen versie maken: https://glitch.com/edit/#!/web-otp .

Gebruik WebOTP vanuit een cross-origin iframe

Het invoeren van een SMS OTP in een cross-origin iframe wordt doorgaans gebruikt voor betalingsbevestiging, vooral bij 3D Secure. Met het gemeenschappelijke formaat om cross-origin iframes te ondersteunen, levert de WebOTP API OTP's gebonden aan geneste oorsprong. Bijvoorbeeld:

  • Een gebruiker bezoekt shop.example om een ​​paar schoenen te kopen met een creditcard.
  • Na het invoeren van het creditcardnummer toont de geïntegreerde betalingsprovider een formulier van bank.example binnen een iframe waarin de gebruiker wordt gevraagd zijn telefoonnummer te verifiëren om snel af te rekenen.
  • bank.example stuurt een sms met een OTP naar de gebruiker, zodat deze deze kan invoeren om zijn identiteit te verifiëren.

Om de WebOTP API vanuit een cross-origin iframe te gebruiken, moet u twee dingen doen:

  • Annoteer zowel de oorsprong van het bovenste frame als de oorsprong van het iframe in het sms-bericht.
  • Configureer het machtigingsbeleid om toe te staan ​​dat het cross-origin iframe OTP rechtstreeks van de gebruiker ontvangt.
WebOTP API binnen een iframe in actie.

Je kunt de demo proberen op https://web-otp-iframe-demo.stackblitz.io .

Annoteer de gebonden oorsprong van het SMS-bericht

Wanneer de WebOTP API wordt aangeroepen vanuit een iframe, moet het sms-bericht de oorsprong van het bovenste frame bevatten, voorafgegaan door @ , gevolgd door de OTP voorafgegaan door # en de oorsprong van het iframe, voorafgegaan door @ op de laatste regel.

Your verification code is 123456

@shop.example #123456 @bank.exmple

Machtigingsbeleid configureren

Om WebOTP in een cross-origin iframe te gebruiken, moet de insluiter toegang tot deze API verlenen via het otp-credentials -machtigingsbeleid om onbedoeld gedrag te voorkomen. Over het algemeen zijn er twee manieren om dit doel te bereiken:

via HTTP-header:

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

via iframe allow attribuut:

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

Bekijk meer voorbeelden van hoe u een toestemmingsbeleid kunt opgeven .

Gebruik WebOTP op desktop

In Chrome ondersteunt WebOTP het luisteren naar sms-berichten die op andere apparaten worden ontvangen om gebruikers te helpen bij het voltooien van de telefoonnummerverificatie op de desktop.

WebOTP-API op desktop.

Voor deze mogelijkheid moet de gebruiker inloggen op hetzelfde Google-account op zowel desktop Chrome als Android Chrome.

Het enige dat ontwikkelaars hoeven te doen is de WebOTP API op hun desktopwebsite te implementeren, op dezelfde manier als op hun mobiele website, maar er zijn geen speciale trucs vereist.

Ga voor meer informatie naar Een telefoonnummer verifiëren op de desktop met behulp van de WebOTP API .

FAQ

Het dialoogvenster verschijnt niet, hoewel ik een correct opgemaakt bericht verzend. Wat gaat er mis?

Er zijn een aantal kanttekeningen bij het testen van de API:

  • Als het telefoonnummer van de afzender is opgenomen in de contactenlijst van de ontvanger, wordt deze API niet geactiveerd vanwege het ontwerp van de onderliggende SMS User Consent API .
  • Als u een werkprofiel op uw Android-apparaat gebruikt en de WebOTP werkt niet, probeer dan Chrome te installeren en te gebruiken op uw persoonlijke profiel (dat wil zeggen hetzelfde profiel waarin u sms-berichten ontvangt).

Controleer het formaat opnieuw om te zien of uw sms correct is opgemaakt.

Is deze API compatibel tussen verschillende browsers?

Chromium en WebKit waren het eens over het sms-berichtformaat en Apple kondigde Safari's ondersteuning hiervoor aan vanaf iOS 14 en macOS Big Sur. Hoewel Safari de WebOTP JavaScript API niet ondersteunt, suggereert het standaardtoetsenbord automatisch dat u het OTP invoert als het sms-bericht aan het formaat voldoet, door input te annoteren met autocomplete=["one-time-code"] .

Is het veilig om sms te gebruiken als authenticatiemiddel?

Hoewel SMS OTP handig is om een ​​telefoonnummer te verifiëren wanneer het nummer voor het eerst wordt opgegeven, moet telefoonnummerverificatie via SMS zorgvuldig worden gebruikt voor herauthenticatie, aangezien telefoonnummers door providers kunnen worden gekaapt en gerecycled. WebOTP is een handig mechanisme voor herauthenticatie en herstel, maar services moeten dit combineren met aanvullende factoren, zoals een kennisuitdaging, of de Web Authentication API gebruiken voor sterke authenticatie.

Waar kan ik bugs in de implementatie van Chrome melden?

Heeft u een bug gevonden in de implementatie van Chrome?

  • Dien een bug in op https://new.crbug.com . Voeg zoveel mogelijk details toe, eenvoudige instructies voor reproductie, en stel Componenten in op Blink>WebOTP .

Hoe kan ik deze functie helpen?

Bent u van plan gebruik te maken van de WebOTP API? Uw publieke steun helpt ons prioriteiten te stellen voor functies en laat andere browserleveranciers zien hoe belangrijk het is om deze te ondersteunen. Stuur een tweet naar @ChromiumDev met de hashtag #WebOTP en laat ons weten waar en hoe je deze gebruikt.

Bronnen