พาสคีย์ช่วยให้บัญชีผู้ใช้ปลอดภัยขึ้น ง่ายขึ้น และใช้งานง่ายขึ้น
การใช้พาสคีย์แทนรหัสผ่านเป็นวิธีที่ยอดเยี่ยมที่เว็บไซต์ทำให้บัญชีผู้ใช้ปลอดภัยขึ้น ใช้งานง่าย ใช้งานง่ายขึ้น และไม่ต้องใช้รหัสผ่าน เมื่อใช้พาสคีย์ ผู้ใช้สามารถลงชื่อเข้าใช้ เว็บไซต์หรือแอป เพียงใช้ลายนิ้วมือ, ใบหน้า หรือ PIN ของอุปกรณ์
คุณต้องสร้างพาสคีย์ เชื่อมโยงกับบัญชีผู้ใช้ และเก็บคีย์สาธารณะของพาสคีย์นั้นไว้ในเซิร์ฟเวอร์ของคุณก่อนที่ผู้ใช้จะลงชื่อเข้าใช้ด้วยพาสคีย์ดังกล่าวได้
วิธีการทำงาน
ระบบจะขอให้ผู้ใช้สร้างพาสคีย์ในกรณีต่อไปนี้
- เมื่อผู้ใช้ลงชื่อเข้าใช้ด้วยรหัสผ่าน
- เมื่อผู้ใช้ลงชื่อเข้าใช้ด้วยพาสคีย์จากอุปกรณ์อื่น (ซึ่งก็คือ
authenticatorAttachment
คือcross-platform
) - ในหน้าเฉพาะที่ผู้ใช้จัดการพาสคีย์ได้
หากต้องการสร้างพาสคีย์ ให้ใช้ WebAuthn API
องค์ประกอบ 4 อย่างของขั้นตอนการลงทะเบียนพาสคีย์ ได้แก่
- แบ็กเอนด์: เซิร์ฟเวอร์แบ็กเอนด์ที่เก็บฐานข้อมูลบัญชีซึ่งจัดเก็บคีย์สาธารณะและข้อมูลเมตาอื่นๆ เกี่ยวกับพาสคีย์
- ฟรอนท์เอนด์: ฟรอนท์เอนด์ที่สื่อสารกับเบราว์เซอร์และส่งคำขอดึงข้อมูลไปยังแบ็กเอนด์
- เบราว์เซอร์: เบราว์เซอร์ของผู้ใช้ที่เรียกใช้ JavaScript
- Authenticator: Authenticator ของผู้ใช้ที่สร้างและจัดเก็บพาสคีย์ ซึ่งอาจอยู่ในอุปกรณ์เดียวกันกับเบราว์เซอร์ (เช่น เมื่อใช้ Windows Hello) หรือบนอุปกรณ์อีกเครื่องหนึ่ง เช่น โทรศัพท์
เส้นทางในการเพิ่มพาสคีย์ใหม่ลงในบัญชีผู้ใช้ที่มีอยู่มีดังนี้
- ผู้ใช้ลงชื่อเข้าใช้เว็บไซต์
- เมื่อลงชื่อเข้าใช้แล้ว ผู้ใช้จะขอสร้างพาสคีย์ที่ส่วนหน้า เช่น ด้วยการกดปุ่ม "สร้างพาสคีย์"
- ฟรอนท์เอนด์จะขอข้อมูลจากแบ็กเอนด์เพื่อสร้างพาสคีย์ เช่น ข้อมูลผู้ใช้ คำถาม และรหัสข้อมูลเข้าสู่ระบบที่จะยกเว้น
- ฟรอนท์เอนด์จะเรียกใช้
navigator.credentials.create()
เพื่อสร้างพาสคีย์ การโทรนี้จะส่งคืนคำสัญญา - ระบบจะสร้างพาสคีย์ขึ้นหลังจากที่ผู้ใช้ให้ความยินยอมโดยใช้การล็อกหน้าจอของอุปกรณ์ คำมั่นสัญญาได้รับการแก้ไขแล้วและระบบส่งข้อมูลรับรองคีย์สาธารณะกลับไปยังฟรอนท์เอนด์
- ฟรอนท์เอนด์จะส่งข้อมูลเข้าสู่ระบบคีย์สาธารณะไปยังแบ็กเอนด์และจัดเก็บรหัสข้อมูลเข้าสู่ระบบและคีย์สาธารณะที่เชื่อมโยงกับบัญชีผู้ใช้เพื่อการตรวจสอบสิทธิ์ในอนาคต
ความเข้ากันได้
เบราว์เซอร์ส่วนใหญ่รองรับ WebAuthn แต่มีช่องโหว่เล็กๆ น้อยๆ โปรดไปที่การสนับสนุนอุปกรณ์ -พาสคีย์s.dev เพื่อดูการผสมผสานระหว่างเบราว์เซอร์และระบบปฏิบัติการที่รองรับการสร้างพาสคีย์
สร้างพาสคีย์ใหม่
ฟรอนท์เอนด์ควรดำเนินการอย่างไรเมื่อมีการส่งคำขอสร้างพาสคีย์ใหม่
การตรวจหาฟีเจอร์
ก่อนแสดงปุ่ม "สร้างพาสคีย์ใหม่" ให้ตรวจสอบดังนี้
- เบราว์เซอร์รองรับ WebAuthn
- อุปกรณ์รองรับ Authenticator ของแพลตฟอร์ม (สร้างพาสคีย์และตรวจสอบสิทธิ์ด้วยพาสคีย์ได้)
- เบราว์เซอร์รองรับ UI แบบมีเงื่อนไขของ WebAuthn
// Availability of `window.PublicKeyCredential` means WebAuthn is usable.
// `isUserVerifyingPlatformAuthenticatorAvailable` means the feature detection is usable.
// `isConditionalMediationAvailable` means the feature detection is usable.
if (window.PublicKeyCredential &&
PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable &&
PublicKeyCredential.isConditionalMediationAvailable) {
// Check if user verifying platform authenticator is available.
Promise.all([
PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable(),
PublicKeyCredential.isConditionalMediationAvailable(),
]).then(results => {
if (results.every(r => r === true)) {
// Display "Create a new passkey" button
}
});
}
เบราว์เซอร์นี้ไม่รองรับพาสคีย์จนกว่าจะเป็นไปตามเงื่อนไขทั้งหมด ไม่ควรแสดงปุ่ม "สร้างพาสคีย์ใหม่" จนกว่าจะถึงเวลาดังกล่าว
ดึงข้อมูลที่สำคัญจากแบ็กเอนด์
เมื่อผู้ใช้คลิกปุ่ม ให้ดึงข้อมูลสำคัญเพื่อโทรหา navigator.credentials.create()
จากแบ็กเอนด์ ดังนี้
challenge
: ระบบทดสอบที่เซิร์ฟเวอร์สร้างขึ้นใน ArrayBuffer สำหรับการลงทะเบียนนี้ ขั้นตอนนี้จำเป็น แต่ไม่มีการใช้งานระหว่างการลงทะเบียน เว้นแต่จะทำเอกสารรับรอง ซึ่งเป็นหัวข้อขั้นสูงที่ไม่ได้กล่าวถึงที่นี่user.id
: รหัสที่ไม่ซ้ำกันของผู้ใช้ ค่านี้ต้องเป็น ArrayBuffer ซึ่งไม่มีข้อมูลส่วนบุคคลที่ระบุตัวบุคคลนั้นได้ เช่น อีเมลหรือชื่อผู้ใช้ ค่า 16 ไบต์แบบสุ่มที่สร้างขึ้นต่อบัญชีจะทำงานได้ดีuser.name
: ช่องนี้ควรมีตัวระบุที่ไม่ซ้ำสำหรับบัญชีที่ผู้ใช้จะรู้จัก เช่น อีเมลหรือชื่อผู้ใช้ ข้อมูลนี้จะแสดง ในตัวเลือกบัญชี (หากใช้ชื่อผู้ใช้ ให้ใช้ค่าเดียวกับในการตรวจสอบสิทธิ์รหัสผ่าน)user.displayName
: ฟิลด์นี้เป็นชื่อที่ต้องระบุและใช้งานง่ายยิ่งขึ้นสำหรับบัญชี ซึ่งไม่จำเป็นต้องไม่ซ้ำกัน และอาจเป็นชื่อที่ผู้ใช้เลือก หากเว็บไซต์ไม่มีค่าที่เหมาะสมที่จะใส่ที่นี่ ให้ส่งสตริงว่าง ข้อมูลนี้อาจแสดงบนตัวเลือกบัญชี โดยขึ้นอยู่กับเบราว์เซอร์excludeCredentials
: ป้องกันการลงทะเบียนอุปกรณ์เดียวกันโดยการระบุรายการรหัสข้อมูลเข้าสู่ระบบที่ลงทะเบียนไว้แล้ว สมาชิกtransports
(หากมี) ควรแสดงผลลัพธ์ของการเรียกใช้getTransports()
ในระหว่างการลงทะเบียนข้อมูลเข้าสู่ระบบแต่ละรายการ
เรียกใช้ WebAuthn API เพื่อสร้างพาสคีย์
โทร navigator.credentials.create()
เพื่อสร้างพาสคีย์ใหม่ API จะแสดงผลสัญญา โดยรอการโต้ตอบของผู้ใช้ที่แสดงกล่องโต้ตอบโมดัล
const publicKeyCredentialCreationOptions = {
challenge: *****,
rp: {
name: "Example",
id: "example.com",
},
user: {
id: *****,
name: "john78",
displayName: "John",
},
pubKeyCredParams: [{alg: -7, type: "public-key"},{alg: -257, type: "public-key"}],
excludeCredentials: [{
id: *****,
type: 'public-key',
transports: ['internal'],
}],
authenticatorSelection: {
authenticatorAttachment: "platform",
requireResidentKey: true,
}
};
const credential = await navigator.credentials.create({
publicKey: publicKeyCredentialCreationOptions
});
// Encode and send the credential to the server for verification.
พารามิเตอร์ที่ไม่ได้อธิบายไว้ข้างต้น ได้แก่
rp.id
: รหัส RP คือโดเมนและเว็บไซต์สามารถระบุโดเมนของตนหรือส่วนต่อท้ายที่ลงทะเบียนได้ ตัวอย่างเช่น หากต้นทางของ RP คือhttps://login.example.com:1337
รหัส RP อาจเป็นlogin.example.com
หรือexample.com
ก็ได้ หากระบุรหัส RP เป็นexample.com
ผู้ใช้จะตรวจสอบสิทธิ์ในlogin.example.com
หรือโดเมนย่อยใดก็ได้ในexample.com
rp.name
: ชื่อของ RPpubKeyCredParams
: ช่องนี้ระบุอัลกอริทึมคีย์สาธารณะที่รองรับของ RP เราขอแนะนำให้ตั้งค่าเป็น[{alg: -7, type: "public-key"},{alg: -257, type: "public-key"}]
ข้อมูลนี้ระบุการรองรับ ECDSA ที่มี P-256 และ RSA PKCS#1 และการสนับสนุนเหล่านี้จะครอบคลุมอย่างครบถ้วนauthenticatorSelection.authenticatorAttachment
: ตั้งค่าเป็น"platform"
หากการสร้างพาสคีย์นี้เป็นการอัปเกรดจากรหัสผ่าน เช่น ในโปรโมชันหลังจากลงชื่อเข้าใช้"platform"
ระบุว่า RP ต้องการตัวตรวจสอบสิทธิ์แพลตฟอร์ม (Authenticator ที่ฝังอยู่ในอุปกรณ์แพลตฟอร์ม) และจะไม่แจ้งให้เสียบ เช่น คีย์ความปลอดภัย USB ผู้ใช้มีตัวเลือกที่ง่ายกว่าในการสร้างพาสคีย์authenticatorSelection.requireResidentKey
: ตั้งค่าเป็นบูลีน "จริง" ข้อมูลเข้าสู่ระบบที่ค้นพบได้ (คีย์ผู้พำนักอาศัย) จะเก็บข้อมูลผู้ใช้ไว้ในพาสคีย์และอนุญาตให้ผู้ใช้เลือกบัญชีได้เมื่อตรวจสอบสิทธิ์authenticatorSelection.userVerification
: ระบุว่าการยืนยันผู้ใช้โดยใช้การล็อกหน้าจออุปกรณ์คือ"required"
,"preferred"
หรือ"discouraged"
ค่าเริ่มต้นคือ"preferred"
ซึ่งหมายความว่า Authenticator อาจข้ามการยืนยันผู้ใช้ ตั้งค่านี้เป็น"preferred"
หรือละเว้นพร็อพเพอร์ตี้
ส่งข้อมูลเข้าสู่ระบบคีย์สาธารณะที่ส่งคืนไปยังแบ็กเอนด์
หลังจากที่ผู้ใช้ให้ความยินยอมโดยใช้การล็อกหน้าจอของอุปกรณ์ ระบบจะสร้างพาสคีย์และแก้ปัญหาสัญญาว่าจะส่งคืนออบเจ็กต์ PublicKeyCredential ไปยังฟรอนท์เอนด์
สัญญาอาจถูกปฏิเสธด้วยเหตุผลต่างๆ คุณจัดการข้อผิดพลาดเหล่านี้ได้โดยตรวจสอบพร็อพเพอร์ตี้ name
ของออบเจ็กต์ Error
ดังนี้
InvalidStateError
: มีพาสคีย์ในอุปกรณ์อยู่แล้ว ระบบจะไม่แสดงกล่องโต้ตอบข้อผิดพลาดแก่ผู้ใช้และเว็บไซต์ไม่ควรถือว่านี่เป็นข้อผิดพลาด ผู้ใช้ต้องการให้อุปกรณ์ในเครื่องลงทะเบียนอย่างถูกต้องNotAllowedError
: ผู้ใช้ยกเลิกการดำเนินการ- ข้อยกเว้นอื่นๆ: มีบางอย่างที่ไม่คาดคิดเกิดขึ้น เบราว์เซอร์จะแสดงกล่องโต้ตอบ ข้อผิดพลาดแก่ผู้ใช้
ออบเจ็กต์ข้อมูลเข้าสู่ระบบคีย์สาธารณะมีพร็อพเพอร์ตี้ต่อไปนี้
id
: รหัส Base64URL ที่เข้ารหัสของพาสคีย์ที่สร้างขึ้น รหัสนี้ช่วยให้เบราว์เซอร์ระบุได้ว่ามีพาสคีย์ที่ตรงกันในอุปกรณ์หรือไม่เมื่อตรวจสอบสิทธิ์ คุณจะต้องจัดเก็บค่านี้ไว้ในฐานข้อมูลบนแบ็กเอนด์rawId
: เวอร์ชัน ArrayBuffer ของรหัสข้อมูลเข้าสู่ระบบresponse.clientDataJSON
: ข้อมูลไคลเอ็นต์ที่เข้ารหัสด้วย ArrayBufferresponse.attestationObject
: ออบเจ็กต์เอกสารรับรองที่เข้ารหัสแบบ ArrayBuffer ซึ่งประกอบด้วยข้อมูลสำคัญ เช่น รหัส RP, แฟล็ก และคีย์สาธารณะauthenticatorAttachment
: ส่งคืน"platform"
เมื่อสร้างข้อมูลเข้าสู่ระบบนี้ในอุปกรณ์ที่รองรับพาสคีย์type
: ช่องนี้ตั้งค่าเป็น"public-key"
เสมอ
หากคุณใช้ไลบรารีในการจัดการออบเจ็กต์ข้อมูลเข้าสู่ระบบคีย์สาธารณะในแบ็กเอนด์ เราขอแนะนำให้ส่งออบเจ็กต์ทั้งหมดไปยังแบ็กเอนด์หลังจากเข้ารหัสบางส่วนด้วย base64url
บันทึกข้อมูลเข้าสู่ระบบ
เมื่อได้รับข้อมูลเข้าสู่ระบบคีย์สาธารณะบนแบ็กเอนด์แล้ว ให้ส่งไปยังไลบรารี FIDO เพื่อประมวลผลออบเจ็กต์
จากนั้น คุณสามารถจัดเก็บข้อมูลที่ได้จากข้อมูลเข้าสู่ระบบไปยังฐานข้อมูลไว้ใช้ในอนาคตได้ รายการต่อไปนี้เป็นพร็อพเพอร์ตี้ทั่วไปบางรายการที่จะบันทึก
- รหัสข้อมูลเข้าสู่ระบบ (คีย์หลัก)
- User ID
- คีย์สาธารณะ
ข้อมูลเข้าสู่ระบบคีย์สาธารณะยังมีข้อมูลต่อไปนี้ซึ่งคุณอาจต้องการบันทึกไว้ในฐานข้อมูลด้วย
- การแจ้งสิทธิ์การสำรองข้อมูล:
true
หากอุปกรณ์มีสิทธิ์สำหรับการซิงค์พาสคีย์ - แฟล็กสถานะข้อมูลสำรอง:
true
หากพาสคีย์ที่สร้างขึ้นได้รับการตั้งค่าให้ซิงค์จริงๆ - การขนส่ง:
รายการการขนส่งที่อุปกรณ์รองรับ
"internal"
หมายความว่าอุปกรณ์รองรับพาสคีย์"hybrid"
หมายความว่าอุปกรณ์รองรับการตรวจสอบสิทธิ์ในอุปกรณ์อื่นด้วย
หากต้องการตรวจสอบสิทธิ์ผู้ใช้ โปรดอ่านลงชื่อเข้าใช้ด้วยพาสคีย์ผ่านการป้อนข้อความอัตโนมัติในแบบฟอร์ม