Trang này được dịch tự động. Đọc phiên bản gốc bằng tiếng Anh tại đây.

Cheatsheet Passkeys. Hướng dẫn thực tế, mẫu triển khai và KPI cho chương trình passkeys.
Cung cấp xác thực người dùng an toàn và đơn giản là yêu cầu bắt buộc đối với các công ty kỹ thuật số vào năm 2024. Passkey, với tư cách là tiêu chuẩn đăng nhập mới, là giải pháp lý tưởng để đáp ứng những nhu cầu này. Tuy nhiên, trải nghiệm người dùng và bảo mật được nâng cao của passkey đối với người dùng đi kèm với một cái giá khi triển khai chúng với tư cách là nhà phát triển. Độ khó triển khai bắt nguồn từ thực tế là passkey tương đối mới - đối với người dùng, và cả nhà phát triển và việc triển khai chúng có thể khá thách thức so với xác thực dựa trên mật khẩu. Trên thực tế, bạn cần ít nhất bốn endpoint API cho xác thực bằng passkey so với một endpoint API cho xác thực bằng mật khẩu.
Một trong những thành phần cốt lõi ở phía máy chủ để cung cấp xác thực passkey là WebAuthn server (phần thư viện màu xanh lá cây). Để có hướng dẫn toàn diện về cách WebAuthn server phù hợp với tích hợp kiến trúc doanh nghiệp rộng lớn hơn, hãy xem bài viết chuyên dụng của chúng tôi.
Nguồn: Yubico
Trong bài đăng trên blog này, chúng tôi so sánh một số thư viện / package / SDK WebAuthn server, phân tích sự khác biệt và đưa ra khuyến nghị cho các nhà phát triển mới làm quen với việc triển khai passkey.
Bài viết gần đây
Để hiểu rõ hơn tại sao lại cần thư viện WebAuthn server ngay từ đầu, hãy xem xét cách thức passkey có thể được triển khai. Về nguyên tắc, có hai cách để tích hợp passkey vào các trang web và ứng dụng:
Trong khi giải pháp passkey của bên thứ ba dễ dàng tích hợp và thường tiết kiệm rất nhiều thời gian kỹ thuật (đặc biệt đối với các trường hợp ngoại lệ, bảo trì, khôi phục, dự phòng và cải thiện trải nghiệm người dùng passkey), một số nhà phát triển chỉ thích tự triển khai mọi thứ.
Thử passkeys trong demo trực tiếp.
Hãy cùng xem việc tự triển khai passkey hoạt động như thế nào. Trong một thiết lập rất cơ bản, cần có một cơ chế để đăng ký (sign-up) và xác thực (đăng nhập). Cả hai quy trình, còn được gọi là các nghi thức (ceremonies) WebAuthn, được xử lý khác nhau, mặc dù luồng tổng thể tuân theo một sơ đồ tương tự:
Vì mọi quá trình đăng ký / đăng nhập đều bao gồm các bước này, backend cần theo dõi người dùng, passkey và các yêu cầu đăng ký / đăng nhập.
Igor Gjorgjioski
Head of Digital Channels & Platform Enablement, VicRoads
We hit 80% mobile passkey activation across 5M+ users without replacing our IDP.
See how VicRoads scaled passkeys to 5M+ users — alongside their existing IDP.
Read the case studyNếu bạn muốn có thêm kiến thức chuyên sâu về cách thức hoạt động của passkey và cách thực hiện một triển khai đơn giản trông như thế nào (mà không sử dụng giải pháp passkey của bên thứ ba), bạn có thể tìm hiểu bài viết trên blog của chúng tôi tại đây.
Trong các tình huống thực tế, khi tự triển khai passkey, hãy ghi nhớ rằng không chỉ là việc cung cấp các endpoint API cần thiết và triển khai cơ bản để đăng ký và đăng nhập. Ngoài ra, bạn cần giải quyết các chủ đề và trường hợp sử dụng sau:
Tuy nhiên, đối với triển khai passkey cơ bản, bạn chỉ cần tuân thủ tiêu chuẩn WebAuthn. Việc triển khai một thư viện WebAuthn server nổi tiếng và được hỗ trợ thường là đủ. Thư viện tạo các tham số WebAuthn server và xác minh các challenge đăng nhập, về cơ bản đảm nhận phần mật mã học và phức tạp nhất cho bạn.
Tham gia Passkeys Community để nhận cập nhật và hỗ trợ.
Tất cả các thư viện WebAuthn server được phân tích đều cung cấp các chức năng cần thiết để cung cấp xác thực passkey. Do đó, chúng tôi đặc biệt chú ý đến các tiêu chí sau:
Các thư viện WebAuthn server sau đây đã được phân tích (sắp xếp theo số lượng sao GitHub giảm dần vào tháng 12 năm 2023):
Xem có bao nhiêu người thực sự dùng passkeys.
type UserModel = { id: string; username: string; currentChallenge?: string; }; /** * It is strongly advised that authenticators get their own DB * table, ideally with a foreign key to a specific UserModel. * * "SQL" tags below are suggestions for column data types and * how best to store data received during registration for use * in subsequent authentications. */ type Authenticator = { // SQL: Encode to base64url then store as `TEXT`. Index this column credentialID: Uint8Array; // SQL: Store raw bytes as `BYTEA`/`BLOB`/etc... credentialPublicKey: Uint8Array; // SQL: Consider `BIGINT` since some authenticators return atomic timestamps as counters counter: number; // SQL: `VARCHAR(32)` or similar, longest possible value is currently 12 characters // Ex: 'singleDevice' | 'multiDevice' credentialDeviceType: CredentialDeviceType; // SQL: `BOOL` or whatever similar type is supported credentialBackedUp: boolean; // SQL: `VARCHAR(255)` and store string array as a CSV string // Ex: ['usb' | 'ble' | 'nfc' | 'internal'] transports?: AuthenticatorTransport[]; };
public class StoredCredential { /// <summary> /// The Credential ID of the public key credential source. /// </summary> public byte[] Id { get; set; } /// <summary> /// The credential public key of the public key credential source. /// </summary> public byte[] PublicKey { get; set; } /// <summary> /// The latest value of the signature counter in the authenticator data from any ceremony using the public key credential source. /// </summary> public uint SignCount { get; set; } /// <summary> /// The value returned from getTransports() when the public key credential source was registered. /// </summary> public AuthenticatorTransport[] Transports { get; set; } /// <summary> /// The value of the BE flag when the public key credential source was created. /// </summary> public bool IsBackupEligible { get; set; } /// <summary> /// The latest value of the BS flag in the authenticator data from any ceremony using the public key credential source. /// </summary> public bool IsBackedUp { get; set; } /// <summary> /// The value of the attestationObject attribute when the public key credential source was registered. /// Storing this enables the Relying Party to reference the credent’al's attestation statement at a later time. /// </summary> public byte[] AttestationObject { get; set; } /// <summary> /// The value of the clientDataJSON attribute when the public key credential source was registered. /// Storing this in combination with the above attestationObject item enables the Relying Party to re-verify the attestation signature at a later time. /// </summary> public byte[] AttestationClientDataJson { get; set; } public List<byte[]> DevicePublicKeys { get; set; } public byte[] UserId { get; set; } public PublicKeyCredentialDescriptor Descriptor { get; set; } public byte[] UserHandle { get; set; } public string AttestationFormat { get; set; } public DateTimeOffset RegDate { get; set; } public Guid AaGuid { get; set; } }
<?php declare(strict_types=1); namespace App\Entity; use App\Repository\PublicKeyCredentialSourceRepository; use DateTimeImmutable; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Uid\AbstractUid; use Symfony\Component\Uid\Uuid; use Webauthn\PublicKeyCredentialSource as BasePublicKeyCredentialSource; use Webauthn\TrustPath\TrustPath; #[ORM\Table(name: 'pk_credential_sources')] #[ORM\Entity(repositoryClass: PublicKeyCredentialSourceRepository::class)] class PublicKeyCredentialSource extends BasePublicKeyCredentialSource { #[ORM\Column(type: Types::DATETIME_IMMUTABLE)] public readonly DateTimeImmutable $createdAt; #[ORM\Id] #[ORM\Column(type: Types::STRING, length: 255)] #[ORM\GeneratedValue(strategy: 'NONE')] private string $id; public function __construct( string $publicKeyCredentialId, string $type, array $transports, string $attestationType, TrustPath $trustPath, AbstractUid $aaguid, string $credentialPublicKey, string $userHandle, int $counter ) { $this->id = Uuid::v4()->toRfc4122(); $this->createdAt = new DateTimeImmutable(); parent::__construct($publicKeyCredentialId, $type, $transports, $attestationType, $trustPath, $aaguid, $credentialPublicKey, $userHandle, $counter); } public function getId(): string { return $this->id; } }
Bảng sau đây cung cấp tổng quan về các thư viện WebAuthn server:
Đăng ký Passkeys Substack để nhận tin mới nhất.
Vì hầu hết các thư viện đều mạnh mẽ ngang nhau và triển khai tiêu chuẩn WebAuthn, chúng tôi đề xuất cây quyết định sau:
Nếu bạn chỉ muốn tìm hiểu thêm về WebAuthn server nói chung mà chưa có một dự án cụ thể nào, chúng tôi có thể đưa ra một số khuyến nghị vì có một số khác biệt giữa các thư viện và tài liệu bổ sung của chúng như tài liệu và các triển khai ví dụ. Vì vậy, đối với các nhà phát triển phần mềm mong muốn khởi động hành trình triển khai passkey của họ, chúng tôi khuyên bạn nên chọn các triển khai sau:
Để hiểu sâu hơn nữa về cách WebAuthn hoạt động ở phía máy chủ, bạn có thể đọc phần Hoạt động của WebAuthn Relying Party rất chi tiết trong WebAuthn RFC, trong đó nêu chi tiết mọi bước cần được triển khai để đăng ký một thông tin xác thực mới (7.1) và xác minh assertion xác thực (7.2).
Đánh giá các yêu cầu passkey và WebAuthn cụ thể của bạn. Trong bài đăng trên blog này, chúng tôi giả định bạn chỉ muốn hỗ trợ passkey dưới dạng thông tin xác thực có thể khám phá (discoverable credentials). Đọc về PublicKeyCredentialCreationOptions và PublicKeyCredentialRequestOptions cùng với các lệnh gọi API WebAuthn phía máy khách navigator.credentials.create() và navigator.credentials.get() để đặt các tham số trong cấu hình SDK WebAuthn server một cách chính xác cho trường hợp sử dụng của bạn.
Đối với tất cả các thư viện WebAuthn server, bạn sẽ cần cung cấp cấu trúc cơ sở dữ liệu phù hợp để lưu trữ / truy cập thông tin sau:
Đối với một số thư viện, có các đề xuất và ví dụ cụ thể (nếu chúng tôi thấy chúng hữu ích, chúng tôi đã cung cấp chúng ở trên). Cần thiết phải hiểu đầy đủ trường WebAuthn nào cần được lưu trữ ở đâu. Đặc biệt chú ý xác định giá trị nào bạn muốn sử dụng cho User ID (user.id). Chúng tôi có một giải thích chi tiết hơn tại đây. Ngoài ra, hãy xem xét điều gì sẽ xảy ra khi một người dùng có thể xóa passkey. Bên cạnh đó, bạn có thể tùy chọn hạn chế việc sử dụng các authenticator nhất định. Danh sách các authenticator hợp lệ liên quan đến passkey có thể được tìm thấy tại đây. Trong trường hợp bạn cũng muốn hỗ trợ và kiểm tra các attestation của khóa bảo mật (security keys), đây là một câu chuyện hoàn toàn khác. Bạn có thể tìm thêm thông tin tại đây.
Xác định thiết bị nào người dùng của bạn sẽ sử dụng passkey và các phương pháp xác thực dự phòng. Trong trường hợp bạn không chắc chắn người dùng của mình sử dụng thiết bị, trình duyệt và hệ điều hành nào, hãy kiểm tra State of Passkeys để biết dữ liệu mới nhất về sự sẵn sàng cho passkey trên các nền tảng, trình duyệt và hệ điều hành. Nếu bạn có các câu hỏi cụ thể về việc áp dụng passkey và tỷ lệ sẵn sàng cho passkey của một số thiết bị nhất định, vui lòng liên hệ với chúng tôi. Chúng tôi rất sẵn lòng cung cấp cho bạn những hiểu biết sâu sắc hơn và giúp đỡ bạn trong chủ đề này (xem thêm bài đăng trên blog mới nhất của chúng tôi về sự sẵn sàng của passkey). Theo góc nhìn về khả năng quan sát (observability), hãy giữ các lỗi WebAuthn phía máy khách và các từ chối xác minh của máy chủ dưới dạng các luồng riêng biệt; để định nghĩa bucket phía máy khách, hãy sử dụng các lỗi WebAuthn. Hơn nữa, bạn nên nhớ rằng đối với Windows 10 và Linux, bạn sẽ cần đưa ra các giải pháp chuyên dụng vì các hệ điều hành này cung cấp ít sự hỗ trợ cho passkey nhất (nếu có).
Xem có bao nhiêu người thực sự dùng passkeys.
Đối với hầu hết mọi ngôn ngữ hoặc framework hiện nay đều có một thư viện WebAuthn server đã được thiết lập tốt. So sánh các thư viện của các ngôn ngữ khác nhau không cho thấy sự vượt trội rõ ràng của một số triển khai nhất định. Thay vào đó, bạn nên sử dụng framework / ngôn ngữ lập trình mà bạn quen thuộc nhất. Ngoài ra, nếu bạn không muốn tự triển khai WebAuthn và lo liệu tất cả những thứ đi kèm, bạn có thể thử một giải pháp xác thực passkey chuyên dụng, dựng sẵn như Corbado. Là một giải pháp xác thực tất cả trong một lấy passkey làm trung tâm, nó đi kèm với thông tin về passkey tuyệt vời, quản lý phiên bản cũng như các phương pháp xác thực dự phòng, vì vậy bạn có thể tập trung vào việc phát triển sản phẩm của mình và bỏ qua vấn đề xác thực. Bạn có thể dùng thử miễn phí với số lượng người dùng không giới hạn tại đây.
Corbado là Authentication Intelligence Platform dành cho các đội CIAM vận hành xác thực consumer ở quy mô lớn. Chúng tôi giúp bạn nhìn thấy điều mà log IDP và các công cụ analytics thông thường không thấy: những thiết bị, phiên bản OS, trình duyệt và trình quản lý credential nào hỗ trợ passkey, tại sao quá trình đăng ký không chuyển thành đăng nhập, luồng WebAuthn fail ở đâu, và khi nào một bản cập nhật OS hay trình duyệt làm hỏng đăng nhập một cách âm thầm — tất cả mà không cần thay thế Okta, Auth0, Ping, Cognito hay IDP nội bộ của bạn. Hai sản phẩm: Corbado Observe bổ sung observability cho passkey và mọi phương thức đăng nhập khác. Corbado Connect mang đến managed passkey với analytics tích hợp (song hành cùng IDP của bạn). VicRoads vận hành passkey cho hơn 5M người dùng với Corbado (kích hoạt passkey +80%). Trao đổi với chuyên gia Passkey →
Đầu tiên hãy kiểm tra xem có thư viện nào cho framework cụ thể của bạn không, sau đó là cho ngôn ngữ lập trình của bạn. Vì tất cả các thư viện được liệt kê đều triển khai tiêu chuẩn WebAuthn như nhau, lựa chọn nên ưu tiên sự quen thuộc với stack công nghệ hiện tại của bạn thay vì sự khác biệt về tính năng giữa các thư viện.
Tối thiểu bạn phải lưu trữ thông tin xác thực, người dùng, challenge và authenticator. Hãy chú ý kỹ đến giá trị bạn gán làm User ID (userHandle) và lập kế hoạch cho các tình huống mà người dùng có thể xóa passkey khỏi thiết bị của họ.
Các thư viện WebAuthn server xử lý các hoạt động mật mã phức tạp nhất: tạo tham số PublicKeyCredentialCreationOptions và PublicKeyCredentialRequestOptions cũng như xác minh các challenge đã được ký. Việc thực hiện đúng các thao tác này từ đầu khó hơn đáng kể so với việc sử dụng một thư viện tuân thủ FIDO đã được kiểm tra và đánh giá.
Windows 10 và Linux cung cấp hỗ trợ passkey ít nhất, do đó cần có các giải pháp dự phòng chuyên dụng cho người dùng trên các nền tảng này. Việc giám sát các lỗi WebAuthn phía máy khách và máy chủ từ chối xác minh dưới dạng các luồng riêng biệt giúp xác định các vấn đề cụ thể của hệ điều hành trong môi trường production.
Xem Corbado phù hợp thế nào với quá trình triển khai passkeys và stack xác thực hiện tại của bạn.
Khám phá Console
Bài viết liên quan
Mục lục