Kasus penggunaan untuk kode akses
Topik ini menjelaskan beberapa kasus penggunaan untuk kode akses.
Kasus penggunaan 1: Bootstrapping
Bootstrapping akun di web.
1.1: Mengautentikasi pengguna
Bagian ini berlaku ketika pihak yang mengandalkan (RP) belum tahu siapa yang mengontrol perangkat klien. Tidak ada artefak browser yang tersedia untuk RP (seperti cookie atau ID kredensial di penyimpanan lokal), meskipun untuk saat ini kami berasumsi bahwa pengguna memiliki akun yang ada dengan RP.
Untuk melakukan bootstrap akun, layani pengguna halaman masuk.
Mulailah dengan meminta pengidentifikasi akun kepada pengguna; biasanya nama pengguna atau alamat email.
Untuk mendukung UI isi otomatis untuk kode akses, pastikan untuk:
username
Tambahkan nilai danwebauthn
ke anotasi lengkapi otomatis yang ada pada bidang input nama pengguna.
<div>
<label for="username">Username:</label>
<input name="username" id="loginform.username"
autocomplete="username webauthn">
</div>
- Pada pemuatan halaman, gunakan
if
pernyataan untuk memeriksa untuk melihat apakah antarmuka pengguna isi otomatis (mediasi kondisional) tersedia, lalu panggilnavigator.credentials.get()
denganmediation: "conditional"
danuserVerification: "preferred"
.
<script>
(async () => {
if (
typeof window.PublicKeyCredential !== 'undefined'
&& typeof window.PublicKeyCredential.isConditionalMediationAvailable === 'function'
) {
const available = await PublicKeyCredential.isConditionalMediationAvailable();
if (available) {
try {
// Retrieve authentication options for `navigator.credentials.get()`
// from your server.
const authOptions = await getAuthenticationOptions();
// This call to `navigator.credentials.get()` is "set and forget."
// The Promise will resolve only if the user successfully interacts
// with the browser's autofill UI to select a passkey.
const webAuthnResponse = await navigator.credentials.get({
mediation: "conditional",
publicKey: {
...authOptions,
// See note about userVerification below.
userVerification: "preferred",
}
});
// Send the response to your server for verification, and
// authenticate the user if the response is valid.
await verifyAutoFillResponse(webAuthnResponse);
} catch (err) {
console.error('Error with conditional UI:', err);
}
}
}
})();
</script>
Hal di atas akan menyebabkan hal-hal berikut terjadi:
- Ambil opsi autentikasi dari server Anda. Mengembalikan setidaknya acak
challenge
danrpId
dikaitkan dengan permintaan autentikasi ini. - Ketika pengguna berinteraksi dengan bidang nama pengguna Anda, browser dan platform akan memeriksa apakah kode akses ada (dalam pengautentikasi platform) yang dapat digunakan dengan pihak yang mengandalkan.
- Jika demikian, maka kode akses akan disajikan kepada pengguna sebagai opsi untuk memilih (bersama dengan kredensial lain yang dapat diisi secara otomatis, seperti nama pengguna yang disimpan di pengelola kata sandi browser). Browser/platform mungkin merender UI yang mirip dengan yang ditunjukkan di bawah ini. Meskipun, tampilan dan nuansa yang tepat bervariasi dari satu platform atau faktor bentuk ke platform lain:
- Jika pengguna memilih kode akses, maka UI platform akan memandu pengguna melalui pemeriksaan verifikasi pengguna (sering kali berbasis biometrik).
- Jika pengguna berhasil melewati verifikasi pengguna,
navigator.credentials.get()
maka panggilan berhasil dan mengembalikan respons WebAuthn. - Jika pengguna memilih kredensial selain kode akses, browser/platform memilih tindakan yang sesuai yang berbeda (seperti mengisi otomatis nama pengguna), dan
navigator.credentials.get()
panggilan tidak teratasi. - Jika pengguna memilih opsi "Passkey dari perangkat lain" (teks yang tepat akan sedikit bervariasi menurut platform), maka browser/platform akan memandu pengguna menggunakan kunci keamanan FIDO2 atau alur Autentikasi Lintas Perangkat (CDA) untuk menggunakan kode akses dari ponsel cerdas atau tablet mereka untuk memberikan respons WebAuthn terhadap
navigator.credentials.get()
panggilan. - Kirim respons WebAuthn ke server Anda untuk verifikasi dan pemeriksaan keamanan tambahan. Jika semua pemeriksaan berhasil, maka mulai sesi terautentikasi untuk pengguna ini.
Inilah sebabnya mengapa ini disebut UI kondisional (atau, lebih umum, mode isi otomatis UI) WebAuthn—antarmuka pengguna pengautentikasi platform yang memandu pengguna melalui verifikasi, atau melalui menggunakan ponsel mereka, ditampilkan hanya jika pengguna memiliki kode akses pada perangkat ini (atau memilih opsi "perangkat lain").
Seperti yang Anda lihat, dalam mode navigator.credentials.get()
ini panggilan berhasil, atau tidak karena tidak pernah diselesaikan. Jika berhasil, hasil panggilan akan mengungkapkan id pengguna dan pernyataan WebAuthn yang ditandatangani, yang akan digunakan pihak yang mengandalkan (RP) untuk mengautentikasi pengguna.
Jika panggilan tidak berhasil, Maka Anda harus melakukan autentikasi pengguna warisan . Anda akan mendapatkan nama pengguna dari halaman pertama ini, dan di halaman berikutnya Anda kemudian melayani tantangan masuk lebih lanjut yang sesuai (seperti kata sandi, menanggapi tantangan SMS, dll.) kepada pengguna. Mereka mungkin termasuk langkah-langkah pemulihan akun jika pengguna lupa kata sandi mereka, atau sebaliknya tidak dapat melewati tantangan masuk reguler. Setelah pengguna melewati semua tantangan masuk, mereka dianggap diautentikasi dan masuk.
Ketika pengguna belum memiliki akun dengan pihak yang mengandalkan (RP), Anda biasanya akan memberi pengguna opsi di halaman masuk untuk membuat akun. Jika pengguna memilih opsi tersebut, maka Anda akan mengumpulkan informasi yang diperlukan dari mereka untuk membuka akun baru. Jika berhasil membuka akun baru, akun tersebut juga dianggap diautentikasi dan masuk.
Setelah pengguna masuk, mungkin sudah waktunya untuk menyiapkan kode akses baru untuk mereka. Lakukan itu untuk salah satu kasus berikut:
- Pengguna melakukan bootstrap akun mereka di perangkat dengan melewati tantangan login non-passkey (seperti menggunakan kata sandi).
- Pengguna baru saja membuat akun baru di pihak yang mengandalkan (RP), dan mereka dianggap masuk karena itu.
- Pengguna menggunakan kode akses, tetapi mereka menggunakan perangkat yang berbeda dari yang saat ini mereka gunakan (dengan memilih "perangkat lain" yang ditunjukkan dalam contoh di atas). Ini dapat dikonfirmasi dengan memeriksa atribut authenticatorAttachment di objek PublicKeyCredential yang dikembalikan.
1.2: Autentikasi lintas perangkat
Jika pengguna menggunakan kode akses dari perangkat lain (seperti ponsel, tablet, atau kunci keamanan FIDO2), maka properti authenticatorAttachment dalam respons autentikasi (getAssertion) akan memiliki nilai cross-platform
.
Dalam skenario tersebut, tawarkan kepada pengguna pilihan untuk membuat kode akses di perangkat lokal mereka. Itu akan menghasilkan pengalaman pengguna yang lebih mulus di masa depan, karena pengguna tidak akan diharuskan untuk menggunakan perangkat mereka yang lain.
1.3: Catatan tentang verifikasi pengguna
Panduan ini menetapkan userVerification ke preferred
, yang berarti bahwa verifikasi pengguna akan dicoba jika memungkinkan.
Beberapa perangkat, seperti komputer desktop dan laptop yang lebih lama, mungkin tidak memiliki sensor biometrik. Pada perangkat tersebut, jika userVerification diatur ke required
, maka pengguna mungkin diminta untuk memasukkan kata sandi masuk sistem mereka untuk setiap masuk menggunakan kode akses. Dan itu bisa membuat mereka frustrasi.
Ketika preferred
digunakan, beberapa pengautentikasi platform akan selalu memerlukan pemeriksaan verifikasi pengguna ketika perangkat memiliki sensor biometrik, tetapi mungkin melewati verifikasi pengguna pada perangkat tanpanya.
Hasil verifikasi pengguna (disampaikan dalam bendera data pengautentikasi) akan mencerminkan hasil verifikasi pengguna yang sebenarnya, dan harus selalu divalidasi terhadap persyaratan Anda di server.
1.4: Memilih pengguna untuk kode akses
Pertama, verifikasi bahwa pengguna cukup terautentikasi dengan kuat menggunakan metode masuk lainnya, termasuk autentikasi multifaktor.
Kedua, pastikan bahwa kombo perangkat dan sistem operasi (OS) pengguna mendukung kode akses dengan memanggil:
PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()
Jika kode akses didukung, maka itu akan mengembalikan true
. Jika tidak didukung, maka akan mengembalikan false
, dan Anda harus membatalkan alur pendaftaran kode akses.
Layani keikutsertaan atau "upsell" modal/interstitial atau halaman kepada pengguna yang menawarkan mereka untuk membuat kode akses:
Tip
Untuk memastikan bahwa pengguna memberikan persetujuan yang sepenuhnya diinformasikan, pertimbangkan untuk menampilkan (atau menautkan ke) deskripsi yang lebih panjang yang menjelaskan bahwa semua pengguna yang dapat membuka kunci perangkat saat ini akan dapat mengakses akun di pihak yang mengandalkan (RP).
Jika pengguna menyetujui, panggil navigator.credentials.create()
dengan opsi yang ditunjukkan dalam contoh di bawah ini:
navigator.credentials.create({
publicKey: {
rp: {
// User-friendly name of your service.
name: "Passkeys Developer",
// Relying party (RP) identifier (hostname/FQDN).
id: passkeys.contoso"
},
user: {
// Persistent, unique identifier for the user account in your backend.
id: Uint8Array.from("0525bc79-5a63-4e47-b7d1-597e25f5caba", c => c.charCodeAt(0)),
// User-friendly identifier often displayed to the user (for example, email address).
name: "amanda@contoso.com",
// Human-readable display name, sometimes displayed by the client.
displayName: "Amanda Brady"
},
// The challenge is a buffer of cryptographically random bytes generated on your backend,
// and should be tightly bound to the current user session.
challenge: Uint8Array.from("XZJscsUqtBH7ZB90t2g0EbZTZYlbSRK6lq7zlN2lJKuoYMnp7Qo2OLzD7xawL3s", c => c.charCodeAt(0)),
pubKeyCredParams: [
// An array of objects describing what public key types are acceptable to a server.
{
"type": "public-key",
"alg": -7 // EC P256
},
{
"type": "public-key",
"alg": -257 // RSA
}
],
excludeCredentials: [
// Array of credential IDs for existing passkeys tied to the user account.
// This avoids creating a new passkey in an authenticator that already has
// a passkey tied to the user account.
{
// Example only.
type: "public-key",
id: new Uint8Array([21, 31, 56, ...]).buffer
},
{
// Example only.
type: "public-key",
id: new Uint8Array([21, 31, 56, ...]).buffer
}
],
authenticatorSelection: {
// Tells the authenticator to create a passkey.
residentKey: "required",
// Tells the client/authenticator to request user verification where possible;
// for example, a biometric or a device PIN.
userVerification: "preferred"
},
"extensions": {
// Returns details about the passkey.
"credProps": true
}
}
})
Catatan
Kami menyarankan agar sebagian besar pihak yang mengandalkan (RPs) tidak menentukan parameter attestation
pengangkutan pengesahan (dengan demikian default ke tidak ada), atau sebaliknya secara eksplisit menggunakan nilai indirect
. Itu menjamin pengalaman pengguna yang paling efisien (platform kemungkinan akan mendapatkan persetujuan dari pengguna untuk jenis ungkapan pengesahan lainnya, yang kemungkinan menghasilkan sebagian kecil dari pembuatan kredensial yang tidak berhasil karena pengguna membatalkan pembuatan).
Saat panggilan WebAuthn diselesaikan, kirim respons ke server Anda, dan kaitkan kunci publik dan ID kredensial yang dikembalikan dengan akun pengguna yang diautentikasi sebelumnya.
Kasus penggunaan 2: Aautikaasi ulang
Menggunakan kode akses untuk autentikasi ulang mungkin diperlukan karena salah satu alasan berikut:
- Pengguna keluar, dan sekarang ingin masuk lagi.
- Sesi pengguna kedaluwarsa karena tidak aktif, dan pengguna ingin masuk lagi.
- Pengguna akan melakukan tindakan sensitif, dan perlu mengonfirmasi kembali kontrol atas sesi pengguna.
Untuk mengautentikasi ulang pengguna dalam setiap situasi ini, Anda akan menggunakan kode akses yang Anda siapkan dalam kasus penggunaan sebelumnya. Panggilan API WebAuthn sama dalam ketiga kasus, tetapi perawatan UI yang Anda berikan sedikit berbeda. Karena akun tertentu ditentukan oleh Anda, platform tidak akan meminta pengguna untuk memilih akun lain di layanan Anda.
2.1: Tindakan sensitif
Mari kita lihat UI untuk alasan ketiga terlebih dahulu—ketika saatnya untuk mengautentikasi ulang tindakan sensitif, periksa apakah Anda memiliki ID kredensial untuk setidaknya satu kode akses untuk pengguna.
Jika tidak ada ID kredensial seperti itu yang tersedia, maka layani tantangan masuk tradisional yang cocok untuk autentikasi ulang, misalnya:
Tip
Kami menyarankan agar pada halaman tantangan masuk ini, pengguna tidak dapat mengubah pengidentifikasi akun mereka. Selain itu, tantangan masuk harus menjadi sesuatu yang tidak sah yang tidak dapat dilewati pengguna perangkat.
Jika, di sisi lain, Anda menemukan setidaknya satu ID kredensial kode akses untuk pengguna, maka Anda dapat menggunakan kode akses untuk autentikasi ulang:
Ketika pengguna siap (dalam contoh di atas, ketika mereka mengklik tombol "Go"), panggil navigator.credentials.get()
, meneruskan semua ID kredensial kode akses pengguna:
navigator.credentials.get({
publicKey: {
challenge: ...,
rpId: ...,
allowCredentials: [{
type: "public-key",
id: new UInt8Array([21, 31, 56, ...]).buffer,
}, {
type: "public-key",
id: new UInt8Array([21, 31, 56, ...]).buffer,
}, {
...
}],
// see note below
userVerification: "preferred",
}
});
Catatan
Pastikan untuk membaca panduan sekeliling userVerification dari kasus penggunaan sebelumnya.
Jika pengguna mengklik "Coba dengan cara lain", maka Anda harus menawarkan metode masuk lainnya (kata sandi, dll.) untuk mengautentikasi ulang mereka (dengan asumsi bahwa pengguna memiliki metode masuk lain yang tersedia untuk mereka).
2.2: Sesi kedaluwarsa dan keluar
Sekarang kita akan memeriksa kasus di mana autentikasi ulang dipicu karena pengguna keluar sendiri, atau pihak yang mengandalkan (RP) kedaluwarsa sesi pengguna. Untuk memfasilitasi itu, RP harus menyimpan beberapa bentuk status sesi pengguna yang mengingatkan mereka tentang akun yang sebelumnya masuk, bahkan ketika mereka mempertimbangkan pengguna keluar (yang dapat dicapai menggunakan artefak browser seperti cookie atau penyimpanan lokal).
Catatan
Pihak yang mengandalkan (RP) mungkin memilih untuk memperlakukan keluar sebagai tindakan komprehensif, dan dengan demikian menghapus semua referensi ke identitas pengguna. RP seperti itu harus memperlakukan masuk berikutnya seperti bootstrap akun, dan mengulangi langkah-langkah yang dijelaskan sebelumnya.
Anda, sebagai RP, kemudian dapat melayani halaman masuk seperti ini:
Jika pengguna mengklik "Gunakan akun yang berbeda", maka Anda harus memasukkan alur bootstrap akun—seperti yang dijelaskan untuk kasus penggunaan sebelumnya—mengulangi langkah-langkah di sana, di mana platform akan memungkinkan pengguna memilih akun mana yang ingin mereka gunakan.
Catatan
Dalam hal ini, Anda juga harus memberi pengguna kemampuan untuk menghapus akun yang disarankan sepenuhnya agar tidak tercantum di halaman masuk.
Tetapi jika pengguna mengklik tombol "Masuk Sebagai", maka periksa apakah Anda memiliki setidaknya satu ID kredensial kode akses yang terkait dengan pengguna. Jika tidak ada ID kredensial yang tersedia, maka layani tantangan masuk tradisional yang cocok untuk autentikasi ulang, misalnya:
Jika, di sisi lain, Anda menemukan setidaknya satu ID kredensial kode akses untuk pengguna, maka Anda dapat menggunakan kode akses untuk autentikasi ulang:
Ketika pengguna siap (dalam contoh di atas, ketika mereka mengklik tombol "Go"), panggil navigator.credentials.get()
, persis seperti yang sudah ditunjukkan (yaitu, dengan meneruskan semua ID kredensial kode akses pengguna).
Jika pengguna mengklik "Coba dengan cara lain", maka Anda harus menawarkan metode masuk lainnya (kata sandi, dll.) untuk mengautentikasi ulang mereka (dengan asumsi bahwa pengguna memiliki metode masuk lain yang tersedia untuk mereka).
Langkah berikutnya
Selanjutnya, lihat Alat dan pustaka untuk kode akses.
Info lebih lanjut
- Pengantunan kode akses
- Passkeys.dev
- Memulai Perjalanan Tanpa Kata Sandi Anda di situs web FIDO Alliance
Windows developer