Membuat pengalaman login yang memanfaatkan kunci sandi sekaligus tetap mengakomodasi pengguna sandi yang ada.
Kunci sandi menggantikan sandi dan membuat akun pengguna di web lebih aman, mudah, dan lebih mudah digunakan. Namun, transisi dari autentikasi berbasis sandi ke autentikasi berbasis kunci sandi dapat mempersulit pengalaman pengguna. Menggunakan isi otomatis formulir untuk menyarankan kunci sandi dapat membantu menciptakan pengalaman terpadu.
Mengapa menggunakan isi otomatis formulir untuk login dengan kunci sandi?
Dengan kunci sandi, pengguna dapat login ke situs cukup menggunakan sidik jari, wajah, atau PIN perangkat.
Idealnya, tidak akan ada pengguna sandi dan alur autentikasi bisa semudah tombol login tunggal. Saat pengguna mengetuk tombol tersebut, dialog pemilih akun akan muncul, pengguna dapat memilih akun, membuka kunci layar untuk memverifikasi dan login.
Namun, transisi dari autentikasi berbasis sandi ke kunci sandi dapat menjadi tantangan. Saat pengguna beralih ke kunci sandi, masih ada orang yang menggunakan sandi dan situs yang harus mengakomodasi kedua jenis pengguna tersebut. Pengguna seharusnya tidak diharapkan untuk mengingat situs tempat mereka beralih ke kunci sandi. Oleh karena itu, meminta pengguna memilih metode yang akan digunakan di awal akan dianggap sebagai UX yang buruk.
Kunci sandi juga merupakan teknologi baru. Menjelaskan dan memastikan pengguna merasa nyaman menggunakannya bisa menjadi tantangan bagi {i>website<i}. Kami dapat mengandalkan pengalaman pengguna yang sudah dikenal untuk mengisi otomatis sandi guna menyelesaikan kedua masalah.
UI kondisional
Untuk membangun pengalaman pengguna yang efisien bagi pengguna kunci sandi dan sandi, Anda dapat menyertakan kunci sandi dalam saran isi otomatis. Ini disebut UI kondisional dan merupakan bagian dari standar WebAuthn.
Segera setelah pengguna mengetuk kolom input nama pengguna, dialog saran isi otomatis akan muncul yang menandai kunci sandi tersimpan beserta saran isi otomatis sandi. Kemudian, pengguna dapat memilih akun dan menggunakan kunci layar perangkat untuk login.
Dengan cara ini, pengguna dapat login ke situs Anda dengan formulir yang sudah ada seolah-olah tidak ada yang berubah, tetapi dengan manfaat keamanan tambahan kunci sandi jika mereka memilikinya.
Cara kerjanya
Untuk melakukan autentikasi dengan kunci sandi, gunakan WebAuthn API.
Empat komponen dalam alur autentikasi kunci sandi adalah: pengguna:
- Backend: Server backend Anda yang menyimpan database akun yang menyimpan kunci publik dan metadata lainnya tentang kunci sandi.
- Frontend: Frontend Anda yang berkomunikasi dengan browser dan mengirim permintaan pengambilan ke backend.
- Browser: Browser pengguna yang menjalankan JavaScript Anda.
- Pengautentikasi: Pengautentikasi pengguna yang membuat dan menyimpan kunci sandi. Ini mungkin di perangkat yang sama dengan browser (misalnya saat menggunakan Windows Hello) atau di perangkat lain, seperti ponsel.
- Segera setelah pengguna membuka frontend, pengguna akan meminta tantangan dari
backend untuk melakukan autentikasi dengan kunci sandi dan memanggil
navigator.credentials.get()
untuk memulai autentikasi dengan kunci sandi. Tindakan ini akan menampilkanPromise
. - Saat pengguna menempatkan kursor di kolom login, browser akan menampilkan dialog isi otomatis sandi termasuk kunci sandi. Dialog autentikasi akan muncul jika pengguna memilih kunci sandi.
- Setelah pengguna memverifikasi identitasnya menggunakan kunci layar perangkat, promise akan diselesaikan dan kredensial kunci publik ditampilkan ke frontend.
- Frontend mengirimkan kredensial kunci publik ke backend. Backend memverifikasi tanda tangan terhadap kunci publik akun yang cocok di database. Jika berhasil, pengguna akan login.
Prasyarat
UI WebAuthn kondisional didukung secara publik di Safari pada iOS 16, iPadOS 16, dan macOS Ventura. Fitur ini juga tersedia di Chrome di Android, macOS, dan Windows 11 22H2.
Melakukan autentikasi dengan kunci sandi melalui isi otomatis formulir
Saat pengguna ingin login, Anda dapat melakukan panggilan get
WebAuthn bersyarat
untuk menunjukkan bahwa kunci sandi dapat disertakan dalam saran isi otomatis. Panggilan kondisional ke API navigator.credentials.get()
WebAuthn tidak menampilkan UI dan tetap tertunda sampai pengguna memilih akun untuk login dari saran isi otomatis. Jika pengguna
memilih kunci sandi, browser akan menyelesaikan promise dengan kredensial,
bukan mengisi formulir login. Halaman tersebut bertanggung jawab untuk
memproses login pengguna.
Anotasi kolom input formulir
Tambahkan atribut autocomplete
ke kolom nama pengguna input
, jika diperlukan.
Tambahkan username
dan webauthn
sebagai tokennya untuk memungkinkannya menyarankan kunci sandi.
<input type="text" name="username" autocomplete="username webauthn" ...>
Deteksi fitur
Sebelum memanggil panggilan WebAuthn API bersyarat, periksa apakah:
- Browser mendukung WebAuthn.
- Browser mendukung UI kondisional WebAuthn.
// Availability of `window.PublicKeyCredential` means WebAuthn is usable.
if (window.PublicKeyCredential &&
PublicKeyCredential.isConditionalMediationAvailable) {
// Check if conditional mediation is available.
const isCMA = await PublicKeyCredential.isConditionalMediationAvailable();
if (isCMA) {
// Call WebAuthn authentication
}
}
Ambil tantangan dari server RP
Ambil tantangan dari server RP yang diperlukan untuk memanggil
navigator.credentials.get()
:
challenge
: Tantangan yang dibuat server di ArrayBuffer. Hal ini diperlukan untuk mencegah serangan replay. Pastikan untuk membuat verifikasi login baru pada setiap upaya login dan abaikan setelah durasi tertentu atau setelah upaya login gagal memvalidasi. Anggap saja seperti token CSRF.allowCredentials
: Array kredensial yang dapat diterima untuk autentikasi ini. Teruskan array kosong untuk memungkinkan pengguna memilih kunci sandi yang tersedia dari daftar yang ditampilkan oleh browser.userVerification
: Menunjukkan apakah verifikasi pengguna yang menggunakan kunci layar perangkat adalah"required"
,"preferred"
, atau"discouraged"
. Defaultnya adalah"preferred"
, yang berarti pengautentikasi mungkin melewati verifikasi pengguna. Tetapkan ini ke"preferred"
atau hapus properti.
Memanggil WebAuthn API dengan flag conditional
untuk mengautentikasi pengguna
Panggil navigator.credentials.get()
untuk mulai menunggu autentikasi pengguna.
// To abort a WebAuthn call, instantiate an `AbortController`.
const abortController = new AbortController();
const publicKeyCredentialRequestOptions = {
// Server generated challenge
challenge: ****,
// The same RP ID as used during registration
rpId: 'example.com',
};
const credential = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal,
// Specify 'conditional' to activate conditional UI
mediation: 'conditional'
});
rpId
: ID RP adalah domain dan situs dapat menentukan domain atau akhiran yang dapat didaftarkan. Nilai ini harus cocok dengan rp.id yang digunakan saat kunci sandi dibuat.
Jangan lupa menentukan mediation: 'conditional'
untuk membuat permintaan menjadi bersyarat.
Mengirim kredensial kunci publik yang ditampilkan ke server RP
Setelah pengguna memilih akun dan memberikan izin menggunakan kunci layar perangkat, promise akan di-resolve dengan menampilkan objek PublicKeyCredential
ke frontend RP.
Promise dapat ditolak karena beberapa alasan. Anda perlu menangani error tersebut dengan semestinya, bergantung pada properti name
objek Error
:
NotAllowedError
: Pengguna telah membatalkan operasi.- Pengecualian lainnya: Terjadi sesuatu yang tidak terduga. Browser akan menampilkan dialog error kepada pengguna.
Objek kredensial kunci publik berisi properti berikut:
id
: ID yang dienkode base64url dari kredensial kunci sandi yang diautentikasi.rawId
: Versi ArrayBuffer ID kredensial.response.clientDataJSON
: ArrayBuffer data klien. Kolom ini berisi informasi seperti tantangan dan asal yang perlu diverifikasi oleh server RP.response.authenticatorData
: ArrayBuffer data pengautentikasi. Kolom ini berisi informasi seperti ID RP.response.signature
: ArrayBuffer tanda tangan. Nilai ini adalah inti kredensial dan perlu diverifikasi di server.response.userHandle
: ArrayBuffer yang berisi ID pengguna yang ditetapkan pada waktu pembuatan. Nilai ini dapat digunakan, bukan ID kredensial, jika server perlu memilih nilai ID yang digunakannya, atau jika backend ingin menghindari pembuatan indeks pada ID kredensial.authenticatorAttachment
: Menampilkanplatform
saat kredensial ini berasal dari perangkat lokal. Ataucross-platform
, terutama saat pengguna menggunakan ponsel untuk login. Jika pengguna perlu menggunakan ponsel untuk login, pertimbangkan untuk meminta mereka membuat kunci sandi di perangkat lokal.type
: Kolom ini selalu ditetapkan ke"public-key"
.
Jika Anda menggunakan library untuk menangani objek kredensial kunci publik di server RP, sebaiknya kirim seluruh objek ke server setelah encoding sebagian menggunakan base64url.
Memverifikasi tanda tangan
Saat Anda menerima kredensial kunci publik di server, teruskan ke library FIDO untuk memproses objek tersebut.
Cari ID kredensial yang cocok dengan properti
id
(Jika Anda perlu
menentukan akun pengguna, gunakan properti
userHandle
yang merupakan user.id
yang Anda tentukan saat membuat kredensial). Lihat
apakah
signature
kredensial dapat diverifikasi dengan kunci publik yang disimpan. Untuk melakukannya, sebaiknya gunakan
library sisi server atau solusi, bukan menulis kode Anda sendiri. Anda dapat menemukan library open source di repo GitHub webauth yang mengagumkan.
Setelah kredensial diverifikasi dengan kunci publik yang cocok, proses login pengguna.