Memverifikasi nomor telepon di web dengan WebOTP API

Membantu pengguna terkait OTP yang diterima melalui SMS

Saat ini, sebagian besar orang di dunia memiliki perangkat seluler dan developer biasanya menggunakan nomor telepon sebagai ID untuk pengguna layanan mereka.

Ada berbagai cara untuk memverifikasi nomor telepon, tetapi sandi sekali pakai (OTP) yang dihasilkan secara acak dan dikirim melalui SMS adalah salah satu cara yang paling umum. Mengirim kode ini kembali ke server developer menunjukkan kontrol atas nomor telepon.

Ide ini telah di-deploy dalam banyak skenario untuk mencapai:

  • Nomor telepon sebagai ID untuk pengguna. Saat mendaftar ke layanan baru, beberapa situs meminta nomor telepon, bukan alamat email, dan menggunakannya sebagai ID akun.
  • Verifikasi dua langkah. Saat login, situs akan meminta kode sekali pakai yang dikirim melalui SMS selain sandi atau faktor pengetahuan lainnya untuk keamanan tambahan.
  • Konfirmasi pembayaran. Saat pengguna melakukan pembayaran, meminta kode sekali pakai yang dikirim melalui SMS dapat membantu memverifikasi niat pengguna tersebut.

Proses saat ini menimbulkan hambatan bagi pengguna. Menemukan OTP dalam pesan SMS, lalu menyalin dan menempelkannya ke formulir akan merepotkan, sehingga menurunkan rasio konversi dalam perjalanan pengguna yang penting. Memudahkan hal ini telah menjadi permintaan lama untuk web dari banyak developer global terbesar. Android memiliki API yang melakukan hal ini dengan tepat. Begitu juga dengan iOS dan Safari.

WebOTP API memungkinkan aplikasi Anda menerima pesan berformat khusus yang terikat dengan domain aplikasi Anda. Dari sini, Anda dapat secara terprogram mendapatkan OTP dari pesan SMS dan memverifikasi nomor telepon untuk pengguna dengan lebih mudah.

Lihat penerapannya

Misalnya, pengguna ingin memverifikasi nomor teleponnya dengan situs. Situs mengirim pesan teks kepada pengguna melalui SMS dan pengguna memasukkan OTP dari pesan untuk memverifikasi kepemilikan nomor telepon.

Dengan WebOTP API, langkah-langkah ini semudah sekali ketuk untuk pengguna, seperti yang ditunjukkan dalam video. Saat pesan teks tiba, sheet bawah akan muncul dan meminta pengguna untuk memverifikasi nomor telepon mereka. Setelah mengklik tombol Verifikasi di sheet bawah, browser akan menempelkan OTP ke dalam formulir dan formulir akan dikirim tanpa perlu menekan Lanjutkan.

Seluruh proses digambarkan dalam diagram pada gambar di bawah.

Diagram WebOTP API

Coba demo sendiri. Aplikasi ini tidak meminta nomor telepon Anda atau mengirim SMS ke perangkat Anda, tetapi Anda dapat mengirimnya dari perangkat lain dengan menyalin teks yang ditampilkan dalam demo. Hal ini berfungsi karena tidak masalah siapa pengirim saat menggunakan WebOTP API.

  1. Buka https://web-otp.glitch.me di Chrome 84 atau yang lebih baru di perangkat Android.
  2. Kirim pesan teks SMS berikut ke ponsel Anda dari ponsel lain.
Your OTP is: 123456.

@web-otp.glitch.me #12345

Apakah Anda menerima SMS dan melihat perintah untuk memasukkan kode ke area input? Demikian cara kerja WebOTP API untuk pengguna.

Penggunaan WebOTP API terdiri dari tiga bagian:

  • Tag <input> yang dianotasi dengan benar
  • JavaScript di aplikasi web Anda
  • Teks pesan berformat yang dikirim melalui SMS.

Saya akan membahas tag <input> terlebih dahulu.

Membuat anotasi pada tag <input>

WebOTP itu sendiri berfungsi tanpa anotasi HTML, tetapi untuk kompatibilitas browser lintas, sebaiknya tambahkan autocomplete="one-time-code" ke tag <input> tempat Anda mengharapkan pengguna memasukkan OTP.

Hal ini memungkinkan Safari 14 atau yang lebih baru menyarankan pengguna untuk mengisi otomatis kolom <input> dengan OTP saat mereka menerima SMS dengan format yang dijelaskan di Memformat pesan SMS meskipun tidak mendukung WebOTP.

HTML

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

Menggunakan WebOTP API

Karena WebOTP sederhana, cukup menyalin dan menempelkan kode berikut untuk melakukannya. Saya akan menjelaskan apa yang terjadi.

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

Deteksi fitur

Deteksi fitur sama seperti banyak API lainnya. Memproses peristiwa DOMContentLoaded akan menunggu hingga hierarki DOM siap dikueri.

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

Memproses OTP

WebOTP API itu sendiri cukup sederhana. Gunakan navigator.credentials.get() untuk mendapatkan OTP. WebOTP menambahkan opsi otp baru ke metode tersebut. Ini hanya memiliki satu properti: transport, yang nilainya harus berupa array dengan string 'sms'.

JavaScript

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

Tindakan ini akan memicu alur izin browser saat pesan SMS masuk. Jika izin diberikan, promise yang ditampilkan akan diselesaikan dengan objek OTPCredential.

Konten objek OTPCredential yang diperoleh

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

Selanjutnya, teruskan nilai OTP ke kolom <input>. Mengirim formulir secara langsung akan menghilangkan langkah yang mengharuskan pengguna mengetuk tombol.

JavaScript

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

Membatalkan pesan

Jika pengguna memasukkan OTP secara manual dan mengirimkan formulir, Anda dapat membatalkan panggilan get() menggunakan instance AbortController di objek 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 => {
    

Memformat pesan SMS

API itu sendiri terlihat cukup sederhana, tetapi ada beberapa hal yang harus Anda ketahui sebelum menggunakannya. Pesan harus dikirim setelah navigator.credentials.get() dipanggil dan harus diterima di perangkat tempat get() dipanggil. Terakhir, pesan harus mematuhi format berikut:

  • Pesan dimulai dengan teks (opsional) yang dapat dibaca manusia yang berisi string alfanumerik empat hingga sepuluh karakter dengan setidaknya satu angka yang meninggalkan baris terakhir untuk URL dan OTP.
  • Bagian domain URL situs yang memanggil API harus didahului oleh @.
  • URL harus berisi tanda pound ('#') diikuti dengan OTP.

Contoh:

Your OTP is: 123456.

@www.example.com #123456

Berikut adalah contoh yang buruk:

Contoh Teks SMS yang salah format Alasan hal ini tidak akan berhasil
Here is your code for @example.com #123456 @ diharapkan menjadi karakter pertama baris terakhir.
Your code for @example.com is #123456 @ diharapkan menjadi karakter pertama baris terakhir.
Your verification code is 123456

@example.com\t#123456
Harus ada satu spasi di antara @host dan #code.
Your verification code is 123456

@example.com  #123456
Harus ada satu spasi di antara @host dan #code.
Your verification code is 123456

@ftp://example.com #123456
Skema URL tidak dapat disertakan.
Your verification code is 123456

@https://example.com #123456
Skema URL tidak dapat disertakan.
Your verification code is 123456

@example.com:8080 #123456
Port tidak dapat disertakan.
Your verification code is 123456

@example.com/foobar #123456
Jalur tidak dapat disertakan.
Your verification code is 123456

@example .com #123456
Tidak ada spasi kosong di domain.
Your verification code is 123456

@domain-forbiden-chars-#%/:<>?@[] #123456
Tidak ada karakter terlarang di domain.
@example.com #123456

Mambo Jumbo
@host dan #code diharapkan menjadi baris terakhir.
@example.com #123456

App hash #oudf08lkjsdf834
@host dan #code diharapkan menjadi baris terakhir.
Your verification code is 123456

@example.com 123456
# tidak ada.
Your verification code is 123456

example.com #123456
@ tidak ada.
Hi mom, did you receive my last text @ dan # tidak ada.

Demo

Coba berbagai pesan dengan demo: https://web-otp.glitch.me

Anda juga dapat melakukan fork dan membuat versi Anda sendiri: https://glitch.com/edit/#!/web-otp.

Menggunakan WebOTP dari iframe lintas origin

Memasukkan OTP SMS ke iframe lintas origin biasanya digunakan untuk konfirmasi pembayaran, terutama dengan 3D Secure. Dengan format umum untuk mendukung iframe lintas origin, WebOTP API mengirimkan OTP yang terikat dengan origin bertingkat. Contoh:

  • Pengguna mengunjungi shop.example untuk membeli sepasang sepatu dengan kartu kredit.
  • Setelah memasukkan nomor kartu kredit, penyedia pembayaran terintegrasi akan menampilkan formulir dari bank.example dalam iframe yang meminta pengguna untuk memverifikasi nomor telepon mereka untuk checkout cepat.
  • bank.example mengirimkan SMS yang berisi OTP kepada pengguna sehingga mereka dapat memasukkannya untuk memverifikasi identitas mereka.

Untuk menggunakan WebOTP API dari dalam iframe lintas-asal, Anda perlu melakukan dua hal:

  • Anotasikan asal frame atas dan asal iframe dalam pesan teks SMS.
  • Konfigurasikan kebijakan izin untuk mengizinkan iframe lintas origin menerima OTP langsung dari pengguna.
WebOTP API dalam iframe sedang beroperasi.

Anda dapat mencoba demo di https://web-otp-iframe-demo.stackblitz.io.

Menambahkan anotasi asal terikat ke pesan teks SMS

Saat WebOTP API dipanggil dari dalam iframe, pesan teks SMS harus menyertakan origin frame atas yang didahului dengan @, diikuti dengan OTP yang didahului dengan #, dan origin iframe yang didahului dengan @ di baris terakhir.

Your verification code is 123456

@shop.example #123456 @bank.exmple

Mengonfigurasi Kebijakan Izin

Untuk menggunakan WebOTP di iframe lintas origin, penyertakan harus memberikan akses ke API ini melalui kebijakan izin kredensial otp untuk menghindari perilaku yang tidak diinginkan. Secara umum, ada dua cara untuk mencapai sasaran ini:

melalui Header HTTP:

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

melalui atribut allow iframe:

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

Lihat contoh selengkapnya tentang cara menentukan kebijakan izin .

Menggunakan WebOTP di desktop

Di Chrome, WebOTP mendukung pemrosesan SMS yang diterima di perangkat lain untuk membantu pengguna menyelesaikan verifikasi nomor telepon di desktop.

WebOTP API di desktop.

Kemampuan ini mengharuskan pengguna login ke Akun Google yang sama di Chrome desktop dan Chrome Android.

Yang perlu dilakukan developer hanyalah menerapkan WebOTP API di situs desktop mereka, dengan cara yang sama seperti yang mereka lakukan di situs seluler, tetapi tidak ada trik khusus yang diperlukan.

Pelajari detail selengkapnya di Memverifikasi nomor telepon di desktop menggunakan WebOTP API.

FAQ

Dialog tidak muncul meskipun saya mengirim pesan yang diformat dengan benar. Apa yang salah?

Ada beberapa peringatan saat menguji API:

  • Jika nomor telepon pengirim disertakan dalam daftar kontak penerima, API ini tidak akan dipicu karena desain SMS User Consent API yang mendasarinya.
  • Jika Anda menggunakan profil kerja di perangkat Android dan WebOTP tidak berfungsi, coba instal dan gunakan Chrome di profil pribadi Anda (yaitu profil yang sama dengan yang Anda gunakan untuk menerima pesan SMS).

Periksa kembali format untuk melihat apakah SMS Anda diformat dengan benar.

Apakah API ini kompatibel di antara browser yang berbeda?

Chromium dan WebKit menyepakati format pesan teks SMS dan Apple mengumumkan dukungan Safari untuk format tersebut mulai iOS 14 dan macOS Big Sur. Meskipun Safari tidak mendukung WebOTP JavaScript API, dengan menambahkan anotasi pada elemen input dengan autocomplete=["one-time-code"], keyboard default akan otomatis menyarankan Anda memasukkan OTP jika pesan SMS mematuhi format.

Apakah aman menggunakan SMS sebagai cara untuk mengautentikasi?

Meskipun OTP SMS berguna untuk memverifikasi nomor telepon saat nomor tersebut pertama kali diberikan, verifikasi nomor telepon melalui SMS harus digunakan dengan hati-hati untuk autentikasi ulang karena nomor telepon dapat dibajak dan didaur ulang oleh operator. WebOTP adalah mekanisme autentikasi ulang dan pemulihan yang praktis, tetapi layanan harus menggabungkannya dengan faktor tambahan, seperti tantangan pengetahuan, atau menggunakan Web Authentication API untuk autentikasi yang kuat.

Di mana saya dapat melaporkan bug dalam penerapan Chrome?

Apakah Anda menemukan bug pada penerapan Chrome?

  • Laporkan bug di crbug.com. Sertakan detail sebanyak mungkin, petunjuk sederhana untuk mereproduksi, dan tetapkan Components ke Blink>WebOTP.

Bagaimana cara membantu fitur ini?

Apakah Anda berencana menggunakan WebOTP API? Dukungan publik Anda membantu kami memprioritaskan fitur, dan menunjukkan kepada vendor browser lain betapa pentingnya mendukung fitur tersebut. Kirim tweet ke @ChromiumDev menggunakan hashtag #WebOTP dan beri tahu kami tempat dan cara Anda menggunakannya.

Resource