Buat pengalaman login yang memanfaatkan kunci sandi sekaligus tetap mengakomodasi pengguna sandi yang ada.
Panduan ini menjelaskan cara menggunakan isi otomatis formulir untuk memungkinkan pengguna login dengan kunci sandi bersama sandi. Menggunakan pengisian otomatis formulir akan menciptakan pengalaman login terpadu, yang menyederhanakan transisi dari sandi ke metode autentikasi kunci sandi yang lebih aman dan mudah digunakan.
Pelajari cara menerapkan UI bersyarat WebAuthn untuk mendukung pengguna kunci sandi dan sandi dengan hambatan minimal di formulir login yang ada.
Mengapa menggunakan isi otomatis formulir untuk login dengan kunci sandi?
Kunci sandi memungkinkan pengguna login ke situs menggunakan sidik jari, wajah, PIN perangkat mereka.
Jika semua pengguna memiliki kunci sandi, alur autentikasi dapat berupa satu tombol login. Mengetuk tombol akan memungkinkan pengguna langsung memverifikasi akun dengan kunci layar, dan login.
Namun, transisi dari sandi ke kunci sandi menimbulkan tantangan. Situs harus mendukung pengguna sandi dan kunci sandi selama periode ini. Meminta pengguna untuk mengingat situs mana yang menggunakan kunci sandi dan meminta mereka untuk memilih metode login di awal akan memberikan pengalaman pengguna yang buruk.
Kunci sandi juga merupakan teknologi baru, dan menjelaskannya dengan jelas dapat menjadi sulit. Menggunakan antarmuka isi otomatis yang sudah dikenal membantu mengatasi tantangan transisi dan kebutuhan pengguna untuk merasa familier.
Menggunakan UI kondisional
Untuk mendukung pengguna kunci sandi dan sandi secara efektif, sertakan kunci sandi dalam saran isi otomatis formulir Anda. Pendekatan ini menggunakan UI kondisional, fitur dari standar WebAuthn.
Saat pengguna berfokus pada kolom input nama pengguna, dialog isi otomatis akan muncul, yang menyarankan kunci sandi tersimpan bersama sandi tersimpan. Pengguna dapat memilih kunci sandi atau sandi dan melanjutkan login, menggunakan kunci layar perangkat jika mereka memilih kunci sandi.
Dengan demikian, pengguna dapat login ke situs Anda dengan formulir login yang sudah ada, tetapi dengan manfaat keamanan tambahan dari kunci sandi jika mereka memilikinya.
Cara kerja autentikasi kunci sandi
Untuk mengautentikasi dengan kunci sandi, Anda menggunakan WebAuthn API.
Empat komponen dalam alur autentikasi kunci sandi adalah:
- Backend: Menyimpan detail akun pengguna, termasuk kunci publik.
- Frontend: Berkomunikasi dengan browser dan mengambil data yang diperlukan dari backend.
- Browser: Menjalankan JavaScript dan berinteraksi dengan WebAuthn API.
- Penyedia kunci sandi: Membuat dan menyimpan kunci sandi. Ini biasanya berupa pengelola sandi seperti Pengelola Sandi Google, atau kunci keamanan.

Proses autentikasi kunci sandi mengikuti alur ini:
- Pengguna membuka halaman login, dan frontend meminta tantangan autentikasi dari backend.
- Backend membuat dan menampilkan tantangan WebAuthn yang terkait dengan akun pengguna.
- Frontend memanggil
navigator.credentials.get()
dengan tantangan untuk memulai autentikasi menggunakan browser. - Browser, yang berinteraksi dengan penyedia kunci sandi, meminta pengguna untuk memilih kunci sandi (sering kali menggunakan dialog isi otomatis yang dipicu oleh memfokuskan kolom login) dan memverifikasi identitas mereka menggunakan kunci layar perangkat atau biometrik.
- Setelah verifikasi pengguna berhasil, penyedia kunci sandi akan menandatangani tantangan, dan browser akan menampilkan kredensial kunci publik yang dihasilkan (termasuk tanda tangan) ke frontend.
- Frontend mengirimkan kredensial ini ke backend.
- Backend memverifikasi tanda tangan kredensial dengan kunci publik yang disimpan pengguna. Jika verifikasi berhasil, backend akan memproses login pengguna.
Mengautentikasi dengan kunci sandi melalui isi otomatis formulir
Untuk memulai autentikasi kunci sandi menggunakan isi otomatis formulir, lakukan panggilan
get
WebAuthn bersyarat saat halaman login dimuat. Panggilan ke
navigator.credentials.get()
ini menyertakan opsi mediation: 'conditional'
.
Permintaan kondisional ke navigator.credentials.get()
API
WebAuthn tidak langsung menampilkan UI. Sebagai gantinya, kolom tersebut menunggu dalam status tertunda hingga pengguna berinteraksi dengan perintah
isi otomatis kolom nama pengguna. Jika pengguna memilih kunci sandi, browser akan me-resolve promise
yang tertunda dengan kredensial untuk memproses login pengguna, sehingga mengabaikan pengiriman
formulir tradisional. Jika pengguna memilih sandi, promise tidak akan di-resolve,
dan alur login sandi standar akan berlanjut.rm. Kemudian, halaman
bertanggung jawab untuk memproses login pengguna.
Menganotasi kolom input formulir
Untuk mengaktifkan isi otomatis kunci sandi, tambahkan atribut autocomplete
ke kolom
input
nama pengguna formulir Anda. Sertakan username
dan webauthn
sebagai
nilai yang dipisahkan spasi.
<input type="text" name="username" autocomplete="username webauthn" autofocus>
Menambahkan autofocus
ke kolom ini akan otomatis memicu perintah isi otomatis saat
memuat halaman, yang langsung menampilkan sandi dan kunci sandi yang tersedia.
Deteksi fitur
Sebelum memanggil panggilan API WebAuthn kondisional, periksa apakah:
- Browser mendukung WebAuthn dengan
PublicKeyCredential
.
- Browser mendukung UI kondisional
WebAuthn dengan
PublicKeyCredential.isConditionalMediationAvailable()
.
Cuplikan berikut menunjukkan cara memeriksa apakah browser mendukung fitur ini:
// 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
}
}
Mengambil informasi dari backend
Backend Anda harus menyediakan beberapa opsi ke frontend untuk memulai
panggilan navigator.credentials.get()
. Opsi ini biasanya diambil sebagai
objek JSON dari endpoint di server Anda.
Properti utama dalam objek opsi meliputi:
challenge
: Tantangan yang dibuat server di ArrayBuffer (biasanya Base64URL yang dienkode untuk transpor JSON). Hal ini penting untuk mencegah serangan replay. Server Anda harus membuat tantangan baru untuk setiap upaya login dan harus membatalkan validasinya setelah beberapa saat atau jika upaya gagal.allowCredentials
: Array deskripsi kredensial. Teruskan array kosong. Tindakan ini akan meminta browser untuk mencantumkan semua kredensial untukrpId
yang ditentukan.userVerification
: Menentukan preferensi Anda untuk verifikasi pengguna, seperti mewajibkan kunci layar perangkat. Nilai default dan yang direkomendasikan adalah"preferred"
. Kemungkinan nilainya adalah:"required"
: Verifikasi pengguna harus dilakukan oleh pengautentikasi (seperti PIN atau biometrik). Operasi akan gagal jika verifikasi tidak dapat dilakukan."preferred"
: Pengautentikasi mencoba verifikasi pengguna, tetapi operasi dapat berhasil tanpanya."discouraged"
: Pengautentikasi harus menghindari verifikasi pengguna jika memungkinkan.
rpId
: ID pihak tepercaya Anda, biasanya domain situs Anda (sepertiexample.com
). Nilai ini harus sama persis denganrp.id
yang digunakan saat kredensial kunci sandi dibuat.
Server Anda harus membuat objek opsi ini. Nilai ArrayBuffer
(seperti
challenge
) harus dienkode Base64URL untuk transpor JSON. Di frontend,
setelah mengurai JSON, gunakan PublicKeyCredential.parseRequestOptionsFromJSON()
untuk mengonversi objek (termasuk mendekode string Base64URL) ke dalam format
yang diharapkan navigator.credentials.get()
.
Cuplikan kode berikut menunjukkan cara mengambil dan mendekode informasi yang diperlukan untuk mengautentikasi dengan kunci sandi.
// Fetch an encoded PubicKeyCredentialRequestOptions from the server.
const _options = await fetch('/webauthn/signinRequest');
// Deserialize and decode the PublicKeyCredentialRequestOptions.
const decoded_options = JSON.parse(_options);
const options = PublicKeyCredential.parseRequestOptionsFromJSON(decoded_options);
...
Memanggil WebAuthn API dengan tanda conditional
untuk mengautentikasi pengguna
Setelah Anda menyiapkan objek publicKeyCredentialRequestOptions
(disebut sebagai
options
dalam contoh kode di bawah), panggil
navigator.credentials.get()
untuk memulai autentikasi kunci sandi
kondisional.
// To abort a WebAuthn call, instantiate an AbortController.
const abortController = new AbortController();
// Invoke WebAuthn to authenticate with a passkey.
const credential = await navigator.credentials.get({
publicKey: options,
signal: abortController.signal,
// Specify 'conditional' to activate conditional UI
mediation: 'conditional'
});
Parameter utama untuk panggilan ini:
publicKey
: Ini harus berupa objekpublicKeyCredentialRequestOptions
(bernamaoptions
dalam contoh) yang Anda ambil dari server dan diproses di langkah sebelumnya.signal
: Meneruskan sinyalAbortController
(sepertiabortController.signal
) memungkinkan Anda membatalkan permintaanget()
secara terprogram. Hal ini berguna saat Anda ingin memanggil panggilan WebAuthn lain.mediation: 'conditional'
: Ini adalah flag penting yang membuat panggilan WebAuthn bersifat kondisional. Tindakan ini akan memberi tahu browser untuk menunggu interaksi pengguna dengan perintah isi otomatis, bukan langsung menampilkan dialog modal.
Mengirim kredensial kunci publik yang ditampilkan ke server RP
Jika pengguna memilih kunci sandi dan berhasil memverifikasi identitasnya (misalnya, menggunakan kunci layar perangkat), promise navigator.credentials.get()
akan diselesaikan. Tindakan ini akan menampilkan objek PublicKeyCredential
ke frontend Anda.
Promise dapat ditolak karena beberapa alasan. Anda harus menangani error ini
dalam kode dengan memeriksa properti name
dari objek Error
:
NotAllowedError
: Pengguna membatalkan operasi, atau tidak ada kunci sandi yang dipilih.AbortError
: Operasi dibatalkan, mungkin oleh kode Anda yang menggunakanAbortController
.- Pengecualian lainnya: Terjadi error yang tidak terduga. Browser biasanya menampilkan dialog error kepada pengguna.
Objek PublicKeyCredential
berisi beberapa properti. Properti utama
yang relevan untuk autentikasi meliputi:
id
: ID yang dienkode base64url dari kredensial kunci sandi yang diautentikasi.rawId
: Versi ArrayBuffer dari ID kredensial.response.clientDataJSON
: ArrayBuffer data klien. Kolom ini berisi informasi seperti verifikasi login dan asal yang harus diverifikasi oleh server Anda.response.authenticatorData
: ArrayBuffer data pengautentikasi. Kolom ini menyertakan informasi seperti ID RP.response.signature
: ArrayBuffer yang berisi tanda tangan. Nilai ini adalah inti kredensial dan server Anda harus memverifikasi tanda tangan ini menggunakan kunci publik yang disimpan untuk kredensial .response.userHandle
: ArrayBuffer yang berisi ID pengguna yang diberikan selama pendaftaran kunci sandi.authenticatorAttachment
: Menunjukkan apakah pengautentikasi adalah bagian dari perangkat klien (platform
) atau eksternal (cross-platform
). Lampirancross-platform
dapat terjadi jika pengguna login dengan ponsel. Dalam kasus tersebut, pertimbangkan untuk meminta mereka membuat kunci sandi di perangkat saat ini untuk kemudahan di masa mendatang.type
: Kolom ini selalu ditetapkan ke"public-key"
.
Untuk mengirim objek PublicKeyCredential
ini ke backend, panggil metode .toJSON()
terlebih dahulu. Metode ini membuat kredensial versi JSON-serializable, yang menangani konversi properti ArrayBuffer
(seperti rawId
, clientDataJSON
, authenticatorData
, signature
, dan
userHandle
) ke string yang dienkode Base64URL dengan benar. Kemudian, gunakan JSON.stringify()
untuk
mengonversi objek ini menjadi string dan kirimkan dalam isi permintaan Anda ke
server.
...
// Encode and serialize the PublicKeyCredential.
const _result = credential.toJSON();
const result = JSON.stringify(_result);
// Encode and send the credential to the server for verification.
const response = await fetch('/webauthn/signinResponse', {
method: 'post',
credentials: 'same-origin',
body: result
});
Memverifikasi tanda tangan
Saat menerima kredensial kunci publik, server backend Anda harus memverifikasi autentisitasnya. Hal ini meliputi:
- Mengurai data kredensial.
- Mencari kunci publik tersimpan yang terkait dengan
id
kredensial. - Memverifikasi
signature
yang diterima dengan kunci publik yang disimpan. - Memvalidasi data lainnya, seperti tantangan dan asal.
Sebaiknya gunakan library FIDO/WebAuthn sisi server untuk menangani operasi kriptografis ini dengan aman. Anda dapat menemukan library open source di repo GitHub awesome-webauthn.
Jika tanda tangan dan semua pernyataan lainnya valid, server dapat membuat pengguna login. Untuk mengetahui langkah-langkah validasi sisi server yang mendetail, lihat Autentikasi kunci sandi sisi server
Memberi sinyal jika kredensial yang cocok tidak ditemukan di backend
Jika server backend Anda tidak dapat menemukan kredensial dengan ID yang cocok selama login, pengguna mungkin sebelumnya telah menghapus kunci sandi ini dari server Anda, tetapi tidak dari penyedia kunci sandinya. Ketidakcocokan ini dapat menyebabkan pengalaman pengguna yang membingungkan jika penyedia kunci sandi terus menyarankan kunci sandi yang tidak lagi berfungsi dengan situs Anda. Untuk meningkatkannya, Anda harus memberi sinyal kepada penyedia kunci sandi untuk menghapus kunci sandi yang tidak digunakan lagi.
Anda dapat menggunakan metode PublicKeyCredential.signalUnknownCredential()
, bagian dari
Webauthn Signal API,
untuk memberi tahu penyedia kunci sandi bahwa kredensial yang ditentukan telah dihapus atau
tidak ada. Panggil metode statis ini di sisi klien jika server Anda
menunjukkan (misalnya, dengan kode status HTTP tertentu seperti 404) bahwa
ID kredensial yang ditampilkan tidak diketahui. Berikan ID RP dan ID kredensial
yang tidak diketahui ke metode ini. Penyedia kunci sandi, jika mendukung sinyal, harus
menghapus kunci sandi.
// Detect authentication failure due to lack of the credential
if (response.status === 404) {
// Feature detection
if (PublicKeyCredential.signalUnknownCredential) {
await PublicKeyCredential.signalUnknownCredential({
rpId: "example.com",
credentialId: "vI0qOggiE3OT01ZRWBYz5l4MEgU0c7PmAA" // base64url encoded credential ID
});
} else {
// Encourage the user to delete the passkey from the password manager nevertheless.
...
}
}
Setelah autentikasi
Bergantung pada cara pengguna login, sebaiknya ikuti alur yang berbeda.
Jika pengguna telah login tanpa kunci sandi
Jika pengguna telah login ke situs Anda tanpa kunci sandi, mereka mungkin tidak memiliki kunci sandi yang terdaftar untuk akun tersebut atau di perangkat mereka saat ini. Ini adalah saat yang tepat untuk mendorong pembuatan kunci sandi. Pertimbangkan pendekatan berikut:
- Mengupgrade sandi ke kunci sandi: Gunakan pembuatan kondisional, fitur WebAuthn yang memungkinkan browser membuat kunci sandi secara otomatis untuk pengguna setelah login sandi berhasil. Hal ini dapat meningkatkan penggunaan kunci sandi secara signifikan dengan menyederhanakan proses pembuatan. Pelajari cara kerjanya dan cara menerapkannya di Membantu pengguna menggunakan kunci sandi dengan lebih lancar
- Meminta pembuatan kunci sandi secara manual: Dorong pengguna untuk membuat kunci sandi. Hal ini dapat efektif setelah pengguna menyelesaikan proses login yang lebih rumit, seperti autentikasi multi-faktor (MFA). Namun, hindari perintah yang berlebihan, yang dapat mengganggu pengalaman pengguna."
Untuk melihat cara mendorong pengguna membuat kunci sandi dan mempelajari praktik terbaik lainnya, lihat contoh di Menginformasikan kunci sandi kepada pengguna.
Jika pengguna telah login dengan kunci sandi
Setelah pengguna berhasil login dengan kunci sandi, Anda memiliki beberapa peluang untuk lebih meningkatkan pengalaman mereka dan mempertahankan konsistensi akun.
Mendorong pembuatan kunci sandi baru setelah autentikasi lintas perangkat
Jika pengguna login dengan kunci sandi menggunakan mekanisme lintas perangkat (misalnya, memindai kode QR dengan ponsel), kunci sandi yang digunakan mungkin tidak disimpan secara lokal di perangkat yang digunakan untuk login. Hal ini dapat terjadi jika:
- Mereka memiliki kunci sandi, tetapi di penyedia kunci sandi yang tidak mendukung sistem operasi atau browser login.
- Pengguna telah kehilangan akses ke penyedia kunci sandi di perangkat login, tetapi kunci sandi masih tersedia di perangkat lain.
Dalam situasi ini, pertimbangkan untuk meminta pengguna membuat kunci sandi baru di
perangkat saat ini. Hal ini dapat menghemat waktu mereka untuk mengulangi proses login lintas perangkat
di masa mendatang. Untuk menentukan apakah pengguna telah login menggunakan
kunci sandi lintas perangkat, periksa properti authenticatorAttachment
kredensial. Jika nilainya "cross-platform"
, hal ini menunjukkan autentikasi lintas perangkat. Jika ya, jelaskan kemudahan membuat kunci sandi baru dan
panduan mereka melalui proses pembuatan.
Menyinkronkan detail kunci sandi dengan penyedia menggunakan sinyal
Untuk memastikan konsistensi dan pengalaman pengguna yang lebih baik, Pihak Penerima (RP) Anda dapat menggunakan WebAuthn Signals API untuk menyampaikan pembaruan tentang kredensial dan informasi pengguna kepada penyedia kunci sandi.
Misalnya, agar daftar kunci sandi pengguna penyedia kunci sandi tetap akurat, buat kredensial di backend tetap sinkron. Anda dapat memberi sinyal bahwa kunci sandi tidak ada lagi sehingga penyedia kunci sandi dapat menghapus kunci sandi yang tidak diperlukan.
Demikian pula, Anda dapat memberikan sinyal jika pengguna memperbarui nama pengguna atau nama tampilannya di layanan Anda, untuk membantu memastikan informasi pengguna yang ditampilkan oleh penyedia kunci sandi (misalnya, dalam dialog pemilihan akun) selalu yang terbaru.
Untuk mempelajari lebih lanjut praktik yang baik agar kunci sandi tetap konsisten, lihat Memastikan kunci sandi konsisten dengan kredensial di server Anda dengan Signal API.
Jangan meminta faktor kedua
Kunci sandi menawarkan perlindungan bawaan yang andal terhadap ancaman umum seperti phishing. Oleh karena itu, faktor autentikasi kedua tidak menambahkan nilai keamanan yang signifikan. Sebaliknya, tindakan ini akan membuat langkah yang tidak perlu bagi pengguna selama login.
Checklist
- Izinkan pengguna login dengan kunci sandi melalui isi otomatis formulir.
- Memberi sinyal saat kredensial pencocokan kunci sandi tidak ditemukan di backend.
- Minta pengguna untuk membuat kunci sandi secara manual jika pengguna belum membuatnya setelah login.
- Buat kunci sandi secara otomatis (pembuatan bersyarat) setelah pengguna login dengan sandi (dan faktor kedua).
- Minta pembuatan kunci sandi lokal jika pengguna telah login dengan kunci sandi lintas perangkat.
- Sinyal daftar kunci sandi yang tersedia dan detail pengguna yang diperbarui (nama pengguna, nama tampilan) ke penyedia setelah login atau saat perubahan terjadi.