Weryfikowanie numerów telefonów w internecie za pomocą interfejsu WebOTP API

Pomoc dla użytkowników z hasłami jednorazowymi otrzymanymi SMS-ami

Czym jest interfejs WebOTP API?

Obecnie większość ludzi na świecie ma urządzenia mobilne, a deweloperzy używają numeru telefonu jako identyfikatora użytkowników swoich usług.

Numery telefonów można weryfikować na różne sposoby. Jednym z nich jest losowo generowane hasło jednorazowe wysyłane SMS-em. Wysłanie tego kodu z powrotem na serwer dewelopera pokazuje, że masz kontrolę nad numerem telefonu.

Ten pomysł został już wdrożony w wielu scenariuszach, aby osiągnąć:

  • Numer telefonu jako identyfikator użytkownika. Podczas rejestracji w nowej usłudze niektóre witryny wymagają podania numeru telefonu zamiast adresu e-mail i używają go jako identyfikatora konta.
  • Weryfikacja dwuetapowa. Podczas logowania strona internetowa prosi o wpisanie jednorazowego kodu SMS-em, który będzie zabezpieczony hasłem i innym elementem wiedzy.
  • Potwierdzenie płatności. Gdy użytkownik dokonuje płatności, prośba o jednorazowy kod wysłany SMS-em może pomóc w zweryfikowaniu zamiaru tej osoby.

Obecny proces utrudnia użytkownikom pracę. Znalezienie hasła jednorazowego w SMS-ie, a następnie skopiowanie go i wklejenie do formularza jest uciążliwe i obniża współczynniki konwersji w kluczowych procesach użytkownika. Wielu największych deweloperów na świecie otrzymało to od dawna prośby o rozwiązanie tego problemu. Android ma interfejs API, który dokładnie tak działa. Podobnie jest z iOS i Safari.

Interfejs WebOTP API umożliwia aplikacji odbieranie specjalnie sformatowanych wiadomości powiązanych z domeną aplikacji. Dzięki temu możesz automatycznie otrzymywać hasło jednorazowe z SMS-a i łatwiej zweryfikować numer telefonu użytkownika.

Zobacz, jak to działa

Załóżmy, że użytkownik chce zweryfikować swój numer telefonu w witrynie. Witryna wysyła użytkownikowi SMS-a, po czym wpisuje hasło jednorazowe, aby potwierdzić własność numeru telefonu.

W interfejsie WebOTP API te czynności można wykonać zaledwie jednym kliknięciem, co pokazano na filmie. Gdy otrzymasz SMS-a, wyświetli się dolna plansza z prośbą o potwierdzenie numeru telefonu. Po kliknięciu przycisku Zweryfikuj w dolnym arkuszu przeglądarka wkleja hasło jednorazowe w formularzu, a formularz jest przesyłany bez konieczności klikania przycisku Dalej.

Cały proces pokazano na ilustracji poniżej.

Diagram interfejsu WebOTP API

Wypróbuj prezentację samodzielnie. Nie prosi o numer telefonu ani nie wysyła SMS-ów na urządzenie, ale możesz wysłać numer z innego urządzenia, kopiując tekst wyświetlony w wersji demonstracyjnej. Jest to możliwe, ponieważ nie ma znaczenia, kto jest nadawcą w przypadku używania interfejsu WebOTP API.

  1. Otwórz stronę https://web-otp.glitch.me w Chrome 84 lub nowszej wersji na urządzeniu z Androidem.
  2. Wyślij na swój telefon tego SMS-a z innego telefonu.
Your OTP is: 123456.

@web-otp.glitch.me #12345

Czy dotarł do Ciebie SMS i widzisz prośbę o wpisanie kodu w obszarze wprowadzania? Tak działa interfejs WebOTP API u użytkowników.

Korzystanie z interfejsu WebOTP API składa się z 3 części:

  • Prawidłowy tag <input> z adnotacjami
  • JavaScript w aplikacji internetowej
  • Sformatowany tekst wiadomości wysłany przez SMS.

Najpierw omówię tag <input>.

Dodawanie adnotacji do tagu <input>

Sam protokół WebOTP działa bez adnotacji HTML, ale aby zapewnić zgodność z różnymi przeglądarkami, zdecydowanie zalecamy dodanie parametru autocomplete="one-time-code" do tagu <input> w miejscu, w którym użytkownik powinien wpisać hasło jednorazowe.

Dzięki temu Safari w wersji 14 lub nowszej może zasugerować użytkownikowi autouzupełnianie pola <input> hasłem jednorazowym po otrzymaniu SMS-a w formacie opisanym w artykule Formatowanie wiadomości SMS, mimo że dany format nie obsługuje WebOTP.

w kodzie HTML,

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

Używanie interfejsu WebOTP API

Ponieważ WebOTP jest prosty, wystarczy skopiować i wkleić poniższy kod. Pokażę Ci, co się dzieje.

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

Wykrywanie funkcji

Wykrywanie funkcji jest takie samo jak w przypadku wielu innych interfejsów API. Wykrywanie zdarzenia DOMContentLoaded spowoduje, że drzewo DOM będzie gotowe do wysyłania zapytań.

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

Przetwarzanie hasła jednorazowego

Sam interfejs WebOTP API jest wystarczająco prosty. Aby uzyskać hasło jednorazowe, użyj adresu navigator.credentials.get(). WebOTP dodaje do tej metody nową opcję otp. Ma tylko jedną właściwość: transport, której wartość musi być tablicą z ciągiem znaków 'sms'.

JavaScript

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

Spowoduje to aktywowanie przepływu uprawnień w przeglądarce, gdy nadejdzie SMS. Jeśli zostanie przyznane uprawnienie, zwrócona obietnica zostanie zrealizowana z obiektem OTPCredential.

Zawartość uzyskanego obiektu OTPCredential

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

Następnie przekaż wartość hasła jednorazowego do pola <input>. Przesłanie formularza bezpośrednio eliminuje konieczność kliknięcia przycisku.

JavaScript

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

Przerwanie wiadomości

Jeśli użytkownik ręcznie wpisze hasło jednorazowe i prześle formularz, możesz anulować wywołanie get() za pomocą instancji AbortController w obiekcie 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 => {
    …

Formatowanie wiadomości SMS

Sam interfejs API powinien wyglądać na dość prosty, ale jest kilka rzeczy, które musisz wiedzieć, zanim go użyjesz. Wiadomość musi zostać wysłana po wywołaniu funkcji navigator.credentials.get() i musi zostać odebrana na urządzeniu, na którym została wywołana funkcja get(). Wiadomość musi też być zgodna z następującym formatem:

  • Wiadomość zaczyna się (opcjonalnym) zrozumiałym dla człowieka tekstem, który zawiera od 4 do 10 znaków alfanumerycznych i co najmniej 1 cyfrę pozostawiającą ostatni wiersz adresu URL i hasła jednorazowego.
  • Część domeny adresu URL witryny, która wywołała interfejs API, musi być poprzedzona ciągiem @.
  • Adres URL musi zawierać podwójny krzyżyk („#”), po którym następuje hasło jednorazowe.

Na przykład:

Your OTP is: 123456.

@www.example.com #123456

Oto złe przykłady:

Przykład nieprawidłowego tekstu SMS Dlaczego to nie działa
Here is your code for @example.com #123456 @ musi być pierwszym znakiem ostatniego wiersza.
Your code for @example.com is #123456 @ musi być pierwszym znakiem ostatniego wiersza.
Your verification code is 123456

@example.com\t#123456
W okresie od @host do #code spodziewana jest 1 spacja.
Your verification code is 123456

@example.com  #123456
W okresie od @host do #code spodziewana jest 1 spacja.
Your verification code is 123456

@ftp://example.com #123456
Nie można uwzględnić schematu adresu URL.
Your verification code is 123456

@https://example.com #123456
Nie można uwzględnić schematu adresu URL.
Your verification code is 123456

@example.com:8080 #123456
Nie można uwzględnić portu.
Your verification code is 123456

@example.com/foobar #123456
Nie można uwzględnić ścieżki.
Your verification code is 123456

@example .com #123456
Brak odstępów w domenie.
Your verification code is 123456

@domain-forbiden-chars-#%/:<>?@[] #123456
Brak zabronionych znaków w domenie.
@example.com #123456

Mambo Jumbo
Ostatni wiersz to @host i #code.
@example.com #123456

App hash #oudf08lkjsdf834
Ostatni wiersz to @host i #code.
Your verification code is 123456

@example.com 123456
Brak elementu #.
Your verification code is 123456

example.com #123456
Brak elementu @.
Hi mom, did you receive my last text Brak atrybutów @ i #.

Przykłady

Wypróbuj różne wiadomości w wersji demonstracyjnej: https://web-otp.glitch.me

Możesz też utworzyć jego rozwidlenie i utworzyć własną wersję: https://glitch.com/edit/#!/web-otp.

Używanie WebOTP z międzyźródłowego elementu iframe

Wpisanie hasła jednorazowego przesłanego SMS-em w elementach iframe z innych domen jest zwykle używane do potwierdzania płatności, zwłaszcza w przypadku 3D Secure. Dzięki wspólnemu formatowi do obsługi elementów iframe z innych domen interfejs WebOTP API dostarcza hasła jednorazowe powiązane z zagnieżdżonymi źródłami. Przykład:

  • Użytkownik odwiedza sklep shop.example, aby kupić parę butów za pomocą karty kredytowej.
  • Po wpisaniu numeru karty kredytowej zintegrowany dostawca usług płatniczych wyświetla w elemencie iframe formularz z usługi bank.example z prośbą o potwierdzenie numeru telefonu na potrzeby szybkiej płatności.
  • bank.example wysyła do użytkownika SMS-a z hasłem jednorazowym, aby mógł on wpisać go w celu potwierdzenia swojej tożsamości.

Aby używać interfejsu WebOTP API z międzyźródłowego elementu iframe, musisz wykonać 2 czynności:

  • W wiadomości tekstowej SMS dodaj adnotacje dotyczące źródła ramki najwyższego poziomu i źródła iframe.
  • Skonfiguruj zasady uprawnień tak, aby element iframe z innych domen mógł otrzymywać hasło jednorazowe bezpośrednio od użytkownika.
Interfejs WebOTP API w elemencie iframe w działaniu.

Możesz ją wypróbować na stronie https://web-otp-iframe-demo.stackblitz.io.

Dodaj adnotacje do elementów źródłowych w SMS-ie

Jeśli zostanie wywołany interfejs WebOTP API z elementu iframe, wiadomość tekstowa SMS musi zawierać źródło ramki najwyższego poziomu poprzedzone ciągiem @, po którym następuje hasło jednorazowe #, a źródło elementu iframe poprzedzające ciąg @ w ostatnim wierszu.

Your verification code is 123456

@shop.example #123456 @bank.exmple

Skonfiguruj zasadę uprawnień

Aby można było używać WebOTP w międzyźródłowym elemencie iframe, umieszczonego elementu musi przyznać dostęp do tego interfejsu API za pomocą zasady uprawnień otp-credentials, co pozwoli uniknąć niezamierzonego zachowania. Ogólnie można osiągnąć ten cel na 2 sposoby:

przez nagłówek HTTP:

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

przez atrybut allow w elemencie iframe:

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

Zobacz więcej przykładów określania zasad dotyczących uprawnień .

Korzystanie z WebOTP na komputerze

W Chrome WebOTP umożliwia odsłuchiwanie SMS-ów odebranych na innych urządzeniach, aby pomóc użytkownikom w weryfikacji numeru telefonu na komputerze.

Interfejs WebOTP API na komputerze.

Ta funkcja wymaga od użytkownika zalogowania się na to samo konto Google w Chrome na komputerze i Chrome na Androida.

Wystarczy, że programiści zaimplementują interfejs WebOTP API w swojej witrynie na komputery w taki sam sposób jak w witrynie mobilnej. Nie są jednak wymagane żadne specjalne sztuczki.

Więcej informacji znajdziesz w artykule Weryfikowanie numeru telefonu na komputerze przy użyciu interfejsu WebOTP API.

Najczęstsze pytania

Okno nie jest wyświetlane, mimo że wysyłam poprawnie sformatowaną wiadomość. Na czym polega problem?

Podczas testowania interfejsu API należy pamiętać o kilku kwestiach:

  • Jeśli numer telefonu nadawcy znajduje się na liście kontaktów odbiorcy, ten interfejs API nie zostanie aktywowany ze względu na konstrukcję SMS User Consent API.
  • Jeśli używasz profilu służbowego na urządzeniu z Androidem, a WebOTP nie działa, zainstaluj Chrome i korzystaj z niego na profilu osobistym (czyli z tego samego profilu, na którym otrzymujesz SMS-y).

Sprawdź format, aby zobaczyć, czy SMS jest prawidłowo sformatowany.

Czy ten interfejs API jest zgodny w różnych przeglądarkach?

Przeglądarka Chromium i WebKit uzgodniły format SMS-ów, a Apple ogłosiło obsługę takiego formatu od wersji iOS 14 i macOS Big Sur. Mimo że Safari nie obsługuje interfejsu WebOTP JavaScript API, dodanie do elementu input adnotacji autocomplete=["one-time-code"] spowoduje, że domyślna klawiatura automatycznie zasugeruje wpisanie hasła jednorazowego, jeśli SMS będzie zgodny z formatem.

Czy korzystanie z SMS-ów jako metody uwierzytelniania jest bezpieczne?

Hasło jednorazowe z SMS-a jest przydatne podczas weryfikacji numeru telefonu, gdy jest on podawany po raz pierwszy, ale do ponownego uwierzytelniania trzeba zachować ostrożność, ponieważ numery telefonów mogą zostać przejęte i ponowne przez operatorów. WebOTP to wygodny mechanizm ponownego uwierzytelniania i przywracania, ale usługi powinny łączyć go z dodatkowymi czynnikami, takimi jak test zabezpieczający logowanie oparty na wiedzy lub korzystać z interfejsu Web Authentication API w celu silnego uwierzytelniania.

Gdzie zgłaszać błędy w implementacji Chrome?

Czy wystąpił błąd związany z implementacją przeglądarki Chrome?

  • Zgłoś błąd na stronie https://new.crbug.com. Podaj jak najwięcej szczegółów, proste instrukcje odtwarzania i ustaw wartość Blink>WebOTP w sekcji Komponenty.

Jak mogę pomóc w tej funkcji?

Czy zamierzasz używać interfejsu WebOTP API? Twoja publiczna pomoc pomaga nam nadać priorytet funkcjom i pokazać innym dostawcom przeglądarek, jak ważne jest ich wsparcie. Wyślij tweeta na adres @ChromiumDev, używając hashtagu #WebOTP, i daj nam znać, gdzie i w jaki sposób go używasz.

Zasoby