แม้ว่าข้อมูลเข้าสู่ระบบ FIDO เช่น พาสคีย์ จะมีจุดประสงค์เพื่อแทนที่รหัสผ่าน แต่ข้อมูลเข้าสู่ระบบ FIDO ส่วนใหญ่ยังช่วยให้ผู้ใช้ไม่ต้องพิมพ์ชื่อผู้ใช้ด้วย ซึ่งจะช่วยให้ผู้ใช้ตรวจสอบสิทธิ์ได้โดยเลือกบัญชีจากรายการพาสคีย์ที่มีสำหรับเว็บไซต์ปัจจุบัน
คีย์ความปลอดภัยเวอร์ชันก่อนหน้าได้รับการออกแบบมาให้เป็นวิธีการตรวจสอบสิทธิ์แบบ 2 ขั้นตอน และต้องใช้รหัสของข้อมูลเข้าสู่ระบบที่เป็นไปได้ จึงต้องป้อนชื่อผู้ใช้ ข้อมูลเข้าสู่ระบบที่คีย์ความปลอดภัยค้นหาได้โดยไม่ต้องทราบรหัสเรียกว่าข้อมูลเข้าสู่ระบบที่ค้นพบได้ ข้อมูลเข้าสู่ระบบ FIDO ส่วนใหญ่ที่สร้างขึ้นในปัจจุบันเป็นข้อมูลเข้าสู่ระบบที่ค้นพบได้ โดยเฉพาะพาสคีย์ที่จัดเก็บไว้ในเครื่องมือจัดการรหัสผ่านหรือในคีย์ความปลอดภัยที่ทันสมัย
หากต้องการตรวจสอบว่าข้อมูลเข้าสู่ระบบของคุณสร้างขึ้นเป็นพาสคีย์ (ข้อมูลเข้าสู่ระบบที่ค้นพบได้) ให้ระบุ residentKey และ requireResidentKey เมื่อสร้างข้อมูลเข้าสู่ระบบ
ฝ่ายที่อาศัย (RP) สามารถใช้ข้อมูลเข้าสู่ระบบที่ค้นพบได้โดยละเว้น allowCredentials ระหว่างการตรวจสอบสิทธิ์พาสคีย์ ในกรณีเหล่านี้ เบราว์เซอร์หรือระบบจะแสดงรายการพาสคีย์ที่ใช้ได้ให้ผู้ใช้เห็น ซึ่งระบุโดยพร็อพเพอร์ตี้ user.name ที่ตั้งค่าไว้ ณ เวลาที่สร้าง หากผู้ใช้เลือกรายการใดรายการหนึ่ง ค่า user.id จะรวมอยู่ในลายเซ็นที่ได้ จากนั้นเซิร์ฟเวอร์จะใช้ข้อมูลดังกล่าวหรือรหัสข้อมูลเข้าสู่ระบบที่แสดงผลเพื่อค้นหาบัญชีแทนชื่อผู้ใช้ที่พิมพ์
UI ตัวเลือกบัญชี เช่น UI ที่กล่าวถึงก่อนหน้านี้ จะไม่แสดงข้อมูลเข้าสู่ระบบที่ค้นพบไม่ได้
requireResidentKey และ residentKey
หากต้องการสร้างพาสคีย์ ให้ระบุ authenticatorSelection.residentKey และ authenticatorSelection.requireResidentKey ใน navigator.credentials.create() โดยใช้ค่าที่ระบุดังต่อไปนี้
async function register () {
// ...
const publicKeyCredentialCreationOptions = {
// ...
authenticatorSelection: {
authenticatorAttachment: 'platform',
residentKey: 'required',
requireResidentKey: true,
}
};
const credential = await navigator.credentials.create({
publicKey: publicKeyCredentialCreationOptions
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
residentKey:
'required': ต้องสร้างข้อมูลเข้าสู่ระบบที่ค้นพบได้ หากสร้างไม่ได้ ระบบจะแสดงผลNotSupportedError'preferred': RP ต้องการสร้างข้อมูลเข้าสู่ระบบที่ค้นพบได้ แต่ยอมรับข้อมูลเข้าสู่ระบบที่ค้นพบไม่ได้'discouraged': RP ต้องการสร้างข้อมูลเข้าสู่ระบบที่ค้นพบไม่ได้ แต่ยอมรับข้อมูลเข้าสู่ระบบที่ค้นพบได้
requireResidentKey:
- พร็อพเพอร์ตี้นี้จะเก็บไว้เพื่อความเข้ากันได้แบบย้อนหลังกับ WebAuthn ระดับ 1 ซึ่งเป็นข้อกำหนดเวอร์ชันเก่า ตั้งค่านี้เป็น
trueหากresidentKeyเป็น'required'มิเช่นนั้นให้ตั้งค่าเป็นfalse
allowCredentials
RP สามารถใช้ allowCredentials ใน navigator.credentials.get() เพื่อควบคุมประสบการณ์การตรวจสอบสิทธิ์ด้วยพาสคีย์ โดยปกติแล้ว ประสบการณ์การตรวจสอบสิทธิ์ด้วยพาสคีย์จะมี 3 ประเภทดังนี้
แสดงตัวเลือกบัญชีโมดัล
เมื่อใช้ข้อมูลเข้าสู่ระบบที่ค้นพบได้ RP จะแสดงตัวเลือกบัญชีโมดัลเพื่อให้ผู้ใช้เลือกบัญชีที่จะลงชื่อเข้าใช้ ตามด้วยการยืนยันตัวตนผู้ใช้ ซึ่งเหมาะสำหรับขั้นตอนการตรวจสอบสิทธิ์ด้วยพาสคีย์ที่เริ่มต้นโดยการกดปุ่มสำหรับการตรวจสอบสิทธิ์ด้วยพาสคีย์โดยเฉพาะ
หากต้องการให้ผู้ใช้ได้รับประสบการณ์การใช้งานนี้ ให้ละเว้นหรือส่งอาร์เรย์ที่ว่างเปล่าไปยังพารามิเตอร์ allowCredentials ใน navigator.credentials.get()
async function authenticate() {
// ...
const publicKeyCredentialRequestOptions = {
// Server generated challenge:
challenge: ****,
// The same RP ID as used during registration:
rpId: 'example.com',
// You can omit `allowCredentials` as well:
allowCredentials: []
};
const credential = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
แสดงการป้อนข้อความอัตโนมัติในแบบฟอร์มพาสคีย์
ตัวเลือกบัญชีโมดัลที่อธิบายไว้ข้างต้นจะทำงานได้ดีหากผู้ใช้ส่วนใหญ่ใช้พาสคีย์และมีพาสคีย์พร้อมใช้งานในอุปกรณ์ที่ใช้ สำหรับผู้ใช้ที่ไม่มีพาสคีย์ในเครื่อง กล่องโต้ตอบโมดัลจะยังคงปรากฏขึ้นและจะเสนอให้ผู้ใช้แสดงพาสคีย์จากอุปกรณ์อื่น ขณะเปลี่ยนให้ผู้ใช้มาใช้พาสคีย์ คุณอาจต้องการหลีกเลี่ยง UI ดังกล่าวสำหรับผู้ใช้ที่ยังไม่ได้ตั้งค่าพาสคีย์
แต่ระบบอาจรวมการเลือกพาสคีย์ไว้ในข้อความแจ้งให้ป้อนข้อความอัตโนมัติสำหรับช่องในแบบฟอร์มการลงชื่อเข้าใช้แบบเดิม ควบคู่ไปกับชื่อผู้ใช้และรหัสผ่านที่บันทึกไว้ ด้วยวิธีนี้ ผู้ใช้ที่มีพาสคีย์จะสามารถ "กรอก" แบบฟอร์มลงชื่อเข้าใช้ได้โดยเลือกพาสคีย์ของตนเอง ผู้ใช้ที่มีคู่ชื่อผู้ใช้/รหัสผ่านที่บันทึกไว้จะเลือกคู่ดังกล่าวได้ และผู้ใช้ที่ไม่มีทั้ง 2 อย่างจะยังคงพิมพ์ชื่อผู้ใช้และรหัสผ่านได้
ประสบการณ์ของผู้ใช้นี้เหมาะอย่างยิ่งเมื่อ RP อยู่ระหว่างการย้ายข้อมูลโดยใช้ทั้งรหัสผ่านและพาสคีย์ผสมกัน
หากต้องการให้ผู้ใช้ได้รับประสบการณ์การใช้งานนี้ นอกเหนือจากการส่งอาร์เรย์ว่างไปยังพร็อพเพอร์ตี้ allowCredentials หรือละเว้นพารามิเตอร์แล้ว ให้ระบุ mediation: 'conditional' ใน navigator.credentials.get() และใส่คำอธิบายประกอบช่องป้อนข้อมูล HTML username ด้วย autocomplete="username webauthn" หรือช่องป้อนข้อมูล password ด้วย autocomplete="password webauthn"
การเรียกใช้ navigator.credentials.get() จะไม่ทำให้ UI แสดงขึ้น แต่หากผู้ใช้โฟกัสที่ช่องป้อนข้อมูลที่มีคำอธิบายประกอบ ระบบจะรวมพาสคีย์ที่ใช้ได้ไว้ในตัวเลือกการป้อนข้อความอัตโนมัติ หากผู้ใช้เลือกบัตร ระบบจะดำเนินการยืนยันการปลดล็อกอุปกรณ์ตามปกติ และหลังจากนั้นสัญญาที่ .get() แสดงผลจะได้รับการแก้ไขพร้อมผลลัพธ์ หากผู้ใช้ไม่เลือกพาสคีย์ สัญญาจะไม่ได้รับการแก้ไข
async function authenticate() {
// ...
const publicKeyCredentialRequestOptions = {
// Server generated challenge:
challenge: ****,
// The same RP ID as used during registration:
rpId: 'example.com',
// You can omit `allowCredentials` as well:
allowCredentials: []
};
const cred = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal,
// Specify 'conditional' to activate conditional UI
mediation: 'conditional'
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
<input type="text" name="username" autocomplete=&qu>ot;username webauthn" ...
ดูวิธีสร้างประสบการณ์ของผู้ใช้นี้ได้ที่ลงชื่อเข้าใช้ด้วยพาสคีย์ผ่านการป้อนข้อความอัตโนมัติในแบบฟอร์ม รวมถึง Codelab ใช้พาสคีย์กับการป้อนข้อความอัตโนมัติในแบบฟอร์มในเว็บแอป
การตรวจสอบสิทธิ์ซ้ำ
ในบางกรณี เช่น เมื่อใช้พาสคีย์เพื่อตรวจสอบสิทธิ์อีกครั้ง ระบบจะทราบตัวระบุของผู้ใช้อยู่แล้ว ในกรณีนี้ เราต้องการใช้พาสคีย์โดยที่เบราว์เซอร์หรือระบบปฏิบัติการไม่แสดงตัวเลือกบัญชีในรูปแบบใดๆ ซึ่งทำได้โดยการส่งรายการรหัสข้อมูลเข้าสู่ระบบในพารามิเตอร์ allowCredentials
ในกรณีนี้ หากมีข้อมูลเข้าสู่ระบบที่ระบุชื่อไว้ในเครื่อง ระบบจะแจ้งให้ผู้ใช้ปลดล็อกอุปกรณ์ทันที หากไม่มี ระบบจะแจ้งให้ผู้ใช้นำเสนออุปกรณ์อื่น (โทรศัพท์หรือคีย์ความปลอดภัย) ที่มีข้อมูลเข้าสู่ระบบที่ถูกต้อง
หากต้องการมอบประสบการณ์ของผู้ใช้เช่นนี้ ให้ระบุรายการรหัสข้อมูลเข้าสู่ระบบสำหรับผู้ใช้ที่ลงชื่อเข้าใช้ RP ควรค้นหาข้อมูลดังกล่าวได้เนื่องจากรู้จักผู้ใช้อยู่แล้ว ระบุรหัสข้อมูลเข้าสู่ระบบเป็นออบเจ็กต์ PublicKeyCredentialDescriptor ในพร็อพเพอร์ตี้ allowCredentials ใน navigator.credentials.get()
async function authenticate() {
// ...
const publicKeyCredentialRequestOptions = {
// Server generated challenge:
challenge: ****,
// The same RP ID as used during registration:
rpId: 'example.com',
// Provide a list of PublicKeyCredentialDescriptors:
allowCredentials: [{
id: ****,
type: 'public-key',
transports: [
'internal',
'hybrid'
]
}, {
id: ****,
type: 'public-key',
transports: [
'internal',
'hybrid'
]
}, ...]
};
const credential = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
ออบเจ็กต์ PublicKeyCredentialDescriptor ประกอบด้วยสิ่งต่อไปนี้
id: รหัสของข้อมูลเข้าสู่ระบบคีย์สาธารณะที่ RP ได้รับจากการลงทะเบียนพาสคีย์type: โดยปกติแล้วช่องนี้จะเป็น'public-key'transports: คำแนะนำเกี่ยวกับการส่งข้อมูลที่อุปกรณ์ซึ่งมีข้อมูลเข้าสู่ระบบนี้รองรับ ซึ่งเบราว์เซอร์ใช้เพื่อเพิ่มประสิทธิภาพ UI ที่ขอให้ผู้ใช้นำเสนออุปกรณ์ภายนอก รายการนี้ (หากระบุ) ควรมีผลลัพธ์ของการเรียกgetTransports()ระหว่างการลงทะเบียนข้อมูลเข้าสู่ระบบแต่ละรายการ
สรุป
ข้อมูลเข้าสู่ระบบที่ค้นพบได้ช่วยให้ประสบการณ์การลงชื่อเข้าใช้ด้วยพาสคีย์ใช้งานง่ายขึ้นมาก โดยอนุญาตให้ผู้ใช้ข้ามการป้อนชื่อผู้ใช้ได้ เมื่อใช้ residentKey, requireResidentKey และ allowCredentials ร่วมกัน RP จะได้รับประสบการณ์การลงชื่อเข้าใช้ที่ทำสิ่งต่อไปนี้ได้
- แสดงตัวเลือกบัญชีโมดัล
- แสดงการป้อนข้อความอัตโนมัติในแบบฟอร์มพาสคีย์
- การตรวจสอบสิทธิ์ซ้ำ
ใช้ข้อมูลเข้าสู่ระบบที่ค้นพบได้ด้วยความระมัดระวัง การทำเช่นนี้จะช่วยให้คุณออกแบบประสบการณ์การลงชื่อเข้าใช้ด้วยพาสคีย์ที่ซับซ้อนซึ่งผู้ใช้จะพบว่าราบรื่นและมีแนวโน้มที่จะมีส่วนร่วมมากขึ้น