---
url: 'https://www.corbado.com/vi/blog/webauthn-conditional-ui-passkeys-autofill'
title: 'Giải thích Kỹ thuật về WebAuthn Conditional UI (Tự động điền Passkey)'
description: 'Conditional UI / Conditional Mediation / Tự động điền passkey là một tính năng mới của passkey. Bài viết này giải thích nó là gì, cách hoạt động và cách triển khai'
lang: 'vi'
author: 'Vincent Delitz'
date: '2026-07-03T07:10:47.207Z'
lastModified: '2026-07-03T07:11:02.785Z'
keywords: 'tự động điền passkey, passkey autofill, conditional mediation, tự động điền WebAuthn, xác thực không mật khẩu, Conditional UI'
category: 'WebAuthn Know-How'
---

# Giải thích Kỹ thuật về WebAuthn Conditional UI (Tự động điền Passkey)

## Key Facts

- **Thông tin xác thực có thể khám phá (khóa thường trú)** là yêu cầu bắt buộc đối với Conditional UI:
  các trình xác thực (authenticator) không lưu trữ dữ liệu dành riêng cho người dùng đối với các khóa không thường trú, khiến cho việc tự động điền
  trở nên bất khả thi đối với chúng.
- Phải gọi **`isConditionalMediationAvailable()`** trước khi bắt đầu bất kỳ luồng Conditional
  UI nào để ngăn chặn các lỗi hiển thị cho người dùng trên các trình duyệt hoặc thiết bị không được hỗ trợ.
- Token **`autocomplete="username webauthn"`** trên trường đầu vào HTML báo hiệu cho
  trình duyệt hiển thị passkey cùng với các đề xuất mật khẩu trong menu thả xuống tự động điền.
- Việc đặt **`mediation: "conditional"`** trong lệnh gọi `navigator.credentials.get()`
  sẽ kích hoạt tính năng tự động điền passkey mà không làm gián đoạn người dùng bằng một hộp thoại phương thức (modal dialog) chặn ngang màn hình.
- Cần có **`AbortController`** để hủy các yêu cầu Conditional UI đang diễn ra vì
  menu thả xuống tự động điền, không giống như các lời nhắc phương thức, không có nút hủy tích hợp sẵn.

## 1. Giới thiệu

Với sự áp dụng nhanh chóng của passkey (và giao thức WebAuthn cơ bản), việc xác thực
đã trở nên an toàn và thân thiện hơn đối với nhiều người dùng. Một trong những tiến bộ
nổi bật của passkey là sự tích hợp của Conditional UI, thường được
gọi là "tự động điền passkey" (passkey autofill) hoặc Conditional Mediation (trong phần tiếp theo, chúng ta sẽ thống nhất sử dụng
thuật ngữ Conditional UI).

Bất chấp việc mới được giới thiệu và đang tiếp tục được các trình duyệt áp dụng, vẫn có một khoảng trống dễ nhận thấy
trong tài liệu kỹ thuật và lời khuyên triển khai đối với
Conditional UI. Bài viết này nhằm mục đích thu hẹp khoảng cách đó bằng cách
giải thích Conditional UI là gì, cách hoạt động và cách
giải quyết các thách thức phổ biến trong quá trình triển khai.

## 2. Conditional UI là gì?

Conditional UI đại diện cho một chế độ mới đối với quy trình đăng nhập passkey / WebAuthn. Nó
hiển thị passkey một cách có chọn lọc trên giao diện người dùng (UI) chỉ khi người dùng có
thông tin xác thực có thể khám phá
(khóa thường trú) - một loại passkey, được đăng ký với
bên phụ thuộc (dịch vụ trực tuyến) và được lưu trữ trong
trình xác thực trên thiết bị của họ (ví dụ: máy tính xách tay, điện thoại thông minh). Các
passkey được hiển thị trong menu thả xuống kết hợp với các mật khẩu được tự động điền,
mang lại sự chuyển đổi liền mạch giữa hệ thống mật khẩu truyền thống và xác thực
passkey tiên tiến, vì người dùng nhìn thấy cả hai trong cùng một ngữ cảnh. Cách tiếp cận thông minh này đảm bảo
rằng người dùng không bị choáng ngợp bởi các tùy chọn không cần thiết và có thể điều hướng quá trình đăng nhập
liền mạch hơn.

Nền tảng của Conditional UI được xây dựng dựa trên ba trụ cột chính:

1. **Tôn trọng Quyền riêng tư của Người dùng:** Đảm bảo
   quyền riêng tư của người dùng bằng cách ngăn chặn việc tiết lộ
   thông tin xác thực có sẵn khi chưa có sự đồng ý của người dùng để tiết lộ các thông tin xác thực này.
2. **Trải nghiệm Người dùng Tốt Ngay cả khi Không có Passkey:** Cho phép các bên phụ thuộc
   triển khai WebAuthn một cách linh hoạt, đảm bảo trải nghiệm người dùng vẫn tốt ngay cả khi
   passkey không khả dụng.
3. **Chuyển đổi Mượt mà từ Mật khẩu sang Passkey:** Kết hợp passkey với
   xác thực dựa trên mật khẩu để làm dịu quá trình chuyển đổi sang
   các phương thức xác thực không mật khẩu,
   tận dụng các mô hình UX quen thuộc của người dùng.

![WebAuthn passkey login conditional ui](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/Web_Authn_passkey_login_conditional_ui_8c8e7b0de5.png)

## 3. Ưu điểm và Nhược điểm của Conditional UI

### 3.1 Ưu điểm

- **Xác thực được Rút gọn:** Quy trình này được tinh giản và hiệu quả hơn, loại bỏ
  sự phức tạp thường liên quan đến nhiều phương thức xác thực.
- **Giảm thiểu Lỗi của Người dùng:** Bằng cách chỉ trình bày các tùy chọn có liên quan, người dùng ít có khả năng
  mắc lỗi hơn trong quá trình xác thực.
- **Nâng cao Sự hài lòng của Người dùng:** Việc loại bỏ các bước không cần thiết đồng nghĩa với việc người dùng có thể đăng nhập nhanh hơn
  và dễ dàng hơn, dẫn đến sự hài lòng của người dùng được cải thiện.
- **Tích hợp Frontend Đơn giản:** Một trong những tính năng nổi bật của Conditional UI là tính
  dễ tích hợp. Các nhà phát triển có thể kết hợp liền mạch nó vào frontend chỉ với một
  vài dòng mã (xem bên dưới).
- **Đăng nhập Không mật khẩu và Không tên người dùng:** Một trong những lợi ích to lớn là Conditional UI
  thúc đẩy không chỉ xác thực không mật khẩu
  mà còn mang lại trải nghiệm không tên người dùng hoặc không tài khoản. Người dùng không phải chịu áp lực ghi nhớ
  địa chỉ email hoặc
  tên người dùng cụ thể từ lúc đăng ký. Thay vào đó, họ có thể dựa vào
  các đề xuất của trình duyệt, bao gồm địa chỉ email/tên
  người dùng được ghép nối với
  passkey phù hợp trong menu tự động điền.
- **Giải quyết Bài toán Khởi động (Bootstrapping Dilemma):** Việc chuyển đổi từ hệ thống tên người dùng - mật khẩu truyền thống
  sang passkey có thể gặp nhiều khó khăn. Conditional UI giải quyết thách thức chuyển đổi này.
  Các trang web có thể khởi tạo lệnh gọi passkey / WebAuthn cùng với lời nhắc mật khẩu thông thường
  mà không phải lo lắng về các lỗi hộp thoại phương thức tiềm ẩn nếu thiết bị thiếu thông tin xác thực
  cần thiết.

### 3.2 Nhược điểm

- **Đường cong Học tập (Learning Curve) đối với Nhà phát triển:** Conditional UI đưa ra một mô hình mới, điều này có nghĩa là
  có một đường cong học tập liên quan đối với các nhà phát triển chưa quen với sự phức tạp của nó.
- **Sự phụ thuộc vào Thiết bị / Trình duyệt:** Sự thành công của Conditional UI phụ thuộc vào thiết bị hoặc
  tính tương thích trình duyệt của người dùng. Do hiện tại không phải tất cả các trình duyệt hoặc thiết bị đều hỗ trợ tính năng này, điều này
  có thể hạn chế khả năng ứng dụng của nó.
- **Trình quản lý Mật khẩu Vô hiệu hóa Autocomplete:** Một số trình quản lý mật khẩu hiện đại và
  tiện ích mở rộng trình duyệt của chúng sửa đổi DOM của trang web và vô hiệu hóa hoặc ghi đè thẻ autocomplete
  trong các trường đầu vào (input fields) để ưu tiên các tính năng tự động hoàn thành của riêng chúng. Điều này có thể dẫn đến một
  trải nghiệm người dùng không nhất quán và kém hài lòng. Vì các tiêu chuẩn đối với Conditional UI
  còn tương đối mới, chúng tôi hy vọng rằng mọi thứ sẽ được cải thiện, để ví dụ: không có hai menu tự động điền nào bị
  chồng lên nhau hoặc menu mong muốn không được hiển thị.

## 4. Conditional UI hoạt động như thế nào?

Trong phần tiếp theo, chúng tôi cung cấp thông tin chi tiết từng bước về các bước đơn lẻ của toàn bộ
luồng Conditional UI:

![WebAuthn Conditional UI Process Flow](https://www.corbado.com/website-assets/653274ad0332e7d69c77e199_webauthn_conditional_ui_process_flow_chart_6a1709e56d.png)

Nhìn chung, quy trình luồng Conditional UI có thể được chia thành hai giai đoạn. Trong
giai đoạn tải trang, logic Conditional UI diễn ra dưới nền, trong khi ở
giai đoạn thao tác của người dùng, người dùng phải chủ động thực hiện một hành động nào đó.

1. **Kiểm tra Tính khả dụng của Conditional UI:** Máy khách (trình duyệt) gọi hàm
   `isConditionalMediationAvailable()` để phát hiện xem kết hợp trình duyệt / thiết bị
   hiện tại có hỗ trợ Conditional UI hay không. Chỉ khi phản hồi là true, quá trình mới
   tiếp tục, nếu không quá trình Conditional UI sẽ bị hủy.
2. **Gọi Endpoint của Conditional UI:** Tiếp theo, máy khách gọi endpoint Conditional UI của máy chủ
   để lấy
   PublicKeyCredentialRequestOptions.
3. **Nhận PublicKeyCredentialRequestOptions:** Máy chủ trả về
   PublicKeyCredentialRequestOptions chứa
   thử thách (challenge) và nhiều
   tùy chọn máy chủ WebAuthn hơn (ví dụ:
   allowCredentials, extensions,
   userVerification).
4. **Bắt đầu Xác thực Cục bộ:** Bằng cách gọi `credentials.get()` với
   PublicKeyCredentialRequestOptions đã nhận và
   thuộc tính `mediation` được đặt thành conditional, quá trình xác thực
   cục bộ trên thiết bị sẽ bắt đầu.
5. **Hiển thị Lựa chọn Tự động điền:** Menu tự động điền cho passkey sẽ bật lên. Cách định dạng
   cụ thể phụ thuộc vào trình duyệt và thiết bị (ví dụ: một số yêu cầu người dùng đặt
   con trỏ vào trường đầu vào, một số tự động hiển thị menu khi tải trang, xem
   bên dưới).
6. **Xác thực Người dùng Cục bộ:** Người dùng chọn passkey từ menu tự động điền mà
   họ muốn sử dụng và xác thực qua hộp thoại xác thực của thiết bị của họ (ví dụ:
   thông qua Face ID, Touch ID,
   Windows Hello).
7. **Gửi Phản hồi của Trình xác thực đến Máy chủ:** Nếu quá trình xác thực người dùng cục bộ
   thành công, phản hồi của trình xác thực sẽ được gửi lại cho
   máy chủ.
8. **Người dùng Đã đăng nhập và Được chuyển hướng:** Sau khi máy chủ nhận được
   phản hồi của trình xác thực, nó sẽ xác thực chữ ký đối với
   khóa công khai của tài khoản người dùng tương ứng trong cơ sở dữ liệu. Nếu xác minh
   thành công, người dùng được cấp quyền truy cập, được đăng nhập và được chuyển hướng đến trang đã đăng nhập.

Bằng cách tuân theo quy trình này, Conditional UI mang đến trải nghiệm
xác thực liền mạch và
thân thiện với người dùng.

## 5. Yêu cầu Kỹ thuật cho Conditional UI

### 5.1 Cấu hình chung

Để Conditional UI hoạt động, một số khía cạnh chung cần được xem xét:

- **Thông số Kỹ thuật của Thông tin xác thực:** Conditional UI được thiết kế đặc biệt để chỉ hoạt động
  với các khóa thường trú / thông tin xác thực có thể khám phá. Lý do đằng sau là
  các trình xác thực không lưu trữ dữ liệu dành riêng cho người dùng (ví dụ: tên,
  tên hiển thị) đối với các khóa không thường trú / thông tin xác thực không thể khám phá. Kết quả là, việc sử dụng
  các khóa này để tự động điền passkey là không thể.
- **Lọc Thông tin xác thực:** Tính năng
  [allowCredentials](https://www.w3.org/TR/webauthn-2/#dom-publickeycredentialrequestoptions-allowcredentials)
  vẫn được hỗ trợ, tạo điều kiện cho các trang web đã nhận thức được
  danh tính của người dùng (ví dụ: nếu tên người dùng được gửi trong lệnh gọi mediation ban đầu do nó
  có thể được lưu trữ trong LocalStorage của trình duyệt) để tinh chỉnh danh sách các thông tin xác thực
  được hiển thị cho người dùng trong quá trình tự động điền.

### 5.2 Phía Máy khách (Client-side)

Để đưa Conditional UI vào hoạt động ở phía máy khách, các yêu cầu sau phải được
đáp ứng:

- **Trình duyệt Tương thích:** Đảm bảo rằng người dùng sử dụng trình duyệt hiện đại có hỗ trợ
  Conditional UI ( xem
  [tại đây](https://caniuse.com/mdn-api_publickeycredential_isconditionalmediationavailable_static) để biết
  độ bao phủ trình duyệt mới nhất).
- **Đã bật JavaScript:** JavaScript phải được bật để tạo điều kiện cho các hoạt động của
  Conditional UI.
- **Kiểm tra Tính khả dụng của Conditional UI:** Bên phụ thuộc (phía
  máy chủ) cần chắc chắn rằng Conditional UI khả dụng ở phía máy khách, khi nó nhận được lệnh gọi mediation của WebAuthn để tránh gây ra bất kỳ
  lỗi nào hiển thị cho người dùng trong các tình huống mà Conditional UI không được hỗ trợ. Để giải quyết vấn đề này,
  khuyến nghị sử dụng phương thức `isConditionalMediationAvailable()` và kiểm tra tính khả dụng kỹ thuật
  của Conditional UI ( xem [bên dưới](#browser-compatibility-check) để biết
  thêm chi tiết).
- **Yêu cầu có Trường đầu vào HTML:** Để Conditional UI hoạt động, bạn cần có một trường đầu vào HTML
  (HTML input field) trong trang web của mình. Nếu không có, bạn cần cung cấp hỗ trợ cho
  quy trình đăng nhập passkey / WebAuthn thông thường được kích hoạt bằng một tương tác của người dùng,
  chẳng hạn như một lần nhấp vào nút.
- **Loại bỏ các Giao thức Hết thời gian chờ (Timeout):** Các tham số hết thời gian chờ (ví dụ: người dùng mất rất nhiều
  thời gian để quyết định chọn một passkey trong menu tự động điền) nên được bỏ qua trong thiết lập này.

### 5.3 Phía Máy chủ (Server-side)

Để Conditional UI hoạt động, một số yêu cầu ở phía máy chủ cũng phải được đáp ứng:

- **WebAuthn Server đang chạy:** Vì chúng ta vẫn đang trong bối cảnh của passkey / WebAuthn, cần
  phải có một máy chủ WebAuthn đang chạy quản lý các thủ tục xác thực.
- **Cung cấp Endpoint Bắt đầu Mediation:** So với các endpoint đăng nhập WebAuthn thông thường, việc
  cung cấp một endpoint khác có chức năng tương tự nhưng có thể xử lý một
  user handle tùy chọn (ví dụ: địa chỉ email, số
  điện thoại, tên người dùng) là rất hữu ích.

## 6. Mẹo Lập trình Thực tế

Kể từ khi chính thức ra mắt Conditional UI vào cuối năm 2022 và các phiên bản beta trước đó, chúng tôi
đã thử nghiệm và làm việc sâu rộng với tính năng này. Trong phần tiếp theo, chúng tôi muốn chia sẻ với bạn
các mẹo thực tế đã giúp ích trong quá trình triển khai Conditional UI.

### 6.1 Ví dụ Toàn diện về Conditional UI

Một ví dụ mã đơn giản và đầy đủ cho phương thức Conditional UI sẽ trông như thế này:

```html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Conditional UI</title>
    </head>
    <body>
        <input type="text" id="username" autocomplete="username webauthn" />

        <script>
            async function passkeyLogin() {
                try {
                    // retrieve the request options (incl. the challenge) from the WebAuthn server
                    let options = await WebAuthnClient.getPublicKeyRequestOptions();

                    const credential = await navigator.credentials.get({
                        publicKey: options.publicKeyCredentialRequestOptions,
                        mediation: "conditional",
                    });

                    const userData = await WebAuthnClient.sendSignedChallenge(credential);
                    window.location.href = "/logged-in";
                } catch (error) {
                    console.log(error);
                }
            }

            passkeyLogin();
        </script>
    </body>
</html>
```

### 6.2 Kiểm tra Tương thích Trình duyệt

Triển khai việc phát hiện Conditional UI đảm bảo rằng Conditional UI chỉ được sử dụng khi
kết hợp thiết bị / trình duyệt hiện tại hỗ trợ tính năng này. Điều này sẽ hoạt động mà không xuất hiện
các lỗi hiển thị cho người dùng khi thiếu hỗ trợ Conditional UI. Việc kết hợp phương thức
`isConditionalMediationAvailable()` trong giao diện người dùng sẽ giải quyết
mối quan tâm này. Nếu có hỗ trợ Conditional UI, quy trình đăng nhập Conditional UI có thể được bắt đầu.

```javascript
// source: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential/isConditionalMediationAvailable#examples

// 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 start endpoint

        let options = await WebAuthnClient.getPublicKeyRequestOptions();

        const credential = await navigator.credentials.get({
            publicKey: options.publicKeyCredentialRequestOptions,
            mediation: "conditional",
        });
        /*
        ...
        */
    }
}
```

### 6.3 Token Tự động điền WebAuthn trong Trường đầu vào

Trường đầu vào nên nhận một token tự động điền HTML webauthn. Điều này báo hiệu cho máy khách
điền passkey vào yêu cầu đang diễn ra. Bên cạnh passkey, các giá trị tự động điền khác cũng có thể được
hiển thị. Các token tự động điền này có thể được kết hợp với các token hiện có khác, ví dụ:

- `autocomplete="username webauthn"`: Bên cạnh việc hiển thị passkey, nó cũng đề xuất
  tự động điền tên người dùng.
- `autocomplete="current-password webauthn"`: Bên cạnh việc hiển thị passkey, nó tiếp tục
  nhắc tự động điền mật khẩu.

```html
<label for="name">Username:</label>
<input type="text" name="name" autocomplete="username webauthn" />
<label for="password">Password:</label>
<input type="password" name="password" autocomplete="current-password webauthn" />
```

Để biết thêm chi tiết, chúng tôi khuyên bạn nên đọc bài đăng trên blog này, cung cấp thêm thông tin chi tiết về
các token autofill / autocomplete cho passkey và mật khẩu.

### 6.4 Thuộc tính Mediation trong Gọi API WebAuthn (Get Call)

Để lấy các passkey có sẵn sau khi đã nhận đối tượng PublicKeyCredentialRequestOptions,
hàm `navigator.credentials.get()` nên được gọi (phục vụ cho cả
passkey và mật khẩu). Đối tượng PublicKeyCredentialRequestOptions cần có
tham số mediation được đặt thành conditional để kích hoạt Conditional UI trên máy khách. Đối với các trường hợp
bạn muốn có lời nhắc passkey theo phương thức (modal) thay thế, hãy xem
mediation ngay lập tức (immediate mediation).

```javascript
const credential = await navigator.credentials.get({
    publicKey: options.publicKeyCredentialRequestOptions,
    mediation: "conditional",
});
```

### 6.5 Hủy Luồng Conditional UI

Nếu không có passkey khả dụng, hoặc người dùng bỏ qua các passkey được đề xuất và nhập
email của họ, luồng Conditional UI sẽ bị dừng. Điều này nhấn mạnh tầm quan trọng của việc luôn
hỗ trợ quá trình đăng nhập passkey / WebAuthn tiêu chuẩn thông qua một hộp thoại phương thức (modal).

Một điểm quan trọng cần nhấn mạnh ở đây là nhu cầu tiềm tàng đối với việc tạm dừng yêu cầu Conditional UI
đang diễn ra. Trái ngược với trải nghiệm phương thức, các menu thả xuống tự động điền không có nút hủy. Theo
thiết kế của WebAuthn, chỉ nên có một
[yêu cầu thông tin xác thực hoạt động duy nhất](https://github.com/w3c/webappsec-credential-management/issues/206)
đang diễn ra tại bất kỳ thời điểm nào. Tiêu chuẩn WebAuthn gợi ý sử dụng
[AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) để
hủy một quy trình WebAuthn, áp dụng cho cả quy trình đăng nhập thông thường và Conditional UI
(xem [tại đây](https://w3c.github.io/webauthn/#sctn-sample-aborting) để biết chi tiết).

Trong dữ liệu đo lường sản xuất (production telemetry), đường dẫn hủy này thường là một kết quả kiểm soát luồng (control-flow) dự kiến,
không phải là lỗi hệ thống. Nếu bạn thấy khối lượng lỗi lớn, bạn cần phân loại các trường hợp dự kiến so với
các trường hợp không mong muốn theo loại hoạt động và thời gian trước khi coi chúng là sự sụt giảm hiệu suất (regression).

Quy trình đăng nhập Conditional UI được kích hoạt ngay khi người dùng truy cập trang.
Nhiệm vụ đầu tiên nên là tạo một đối tượng `AbortController` có phạm vi toàn cục. Đối tượng này sẽ đóng vai trò
là tín hiệu để máy khách của bạn chấm dứt yêu cầu tự động điền, đặc biệt là nếu người dùng
quyết định thực hiện quy trình đăng nhập passkey thông thường.
Đảm bảo rằng `AbortController` có thể được gọi bởi các hàm khác và được thiết lập lại (reset) nếu
quy trình Conditional UI phải khởi động lại. Sử dụng thuộc tính signal trong
lệnh gọi `navigator.credentials.get()`, kết hợp tín hiệu `AbortController` của bạn làm
giá trị của nó. Điều này báo hiệu cho hàm passkey / WebAuthn rằng yêu cầu phải bị dừng nếu
tín hiệu bị hủy. Hãy nhớ thiết lập một `AbortController` mới mỗi khi bạn
kích hoạt Conditional UI. Việc sử dụng `AbortController` đã bị hủy (aborted) sẽ dẫn đến việc hủy ngay lập tức
hàm passkey / WebAuthn. Các bước còn lại phù hợp với quy trình đăng nhập
passkey thông thường. Trong phần sau, bạn sẽ thấy một
ví dụ mã của các bước được đề cập:

```html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Conditional UI</title>
    </head>
    <body>
        <input type="text" id="username" autocomplete="username webauthn" />

        <script>
            async function passkeyLogin() {
                try {
                    // retrieve the request options (incl. the challenge) from the WebAuthn server
                    let options = await WebAuthnClient.getPublicKeyRequestOptions();

                    const credential = await navigator.credentials.get({
                        publicKey: options.publicKeyCredentialRequestOptions,
                        mediation: "conditional",
                    });

                    const userData = await WebAuthnClient.sendSignedChallenge(credential);
                    window.location.href = "/logged-in";
                } catch (error) {
                    console.log(error);
                }
            }

            passkeyLogin();
        </script>
    </body>
</html>
```

Trong trường hợp không hỗ trợ Conditional UI, hãy điều hướng người dùng hướng tới quy trình đăng nhập
passkey thông thường. Cung cấp đường dẫn này là
quan trọng đối với những người dùng dựa vào
khóa bảo mật phần cứng (ví dụ:
YubiKeys) hoặc những người buộc phải sử dụng khóa không thường trú /
thông tin xác thực không thể khám phá do các giới hạn của trình xác thực.

### 6.6 Conditional UI trong Các Ứng dụng Gốc (Native Apps)

Khi bạn phát triển một ứng dụng gốc, ví dụ: cho
iOS hoặc Android,
Conditional UI cũng sẽ hoạt động. Sẽ không có vấn đề gì nếu bạn triển khai nó một cách tự nhiên (natively) bằng
Flutter, Kotlin hay Swift, hoặc nếu bạn quyết định sử dụng
Chrome Custom Tabs (CCT) hay
SFSafariViewController hay
SFAuthenticationSession /
ASWebAuthenticationSession. Cả hai phương pháp tiếp cận đều hỗ trợ
Conditional UI.

#### 6.6.1 Conditional UI trong Ứng dụng iOS

Nhìn chung, chúng tôi hầu như không tìm thấy tài liệu nào về cách triển khai hỗ trợ Conditional UI
cho ứng dụng iOS. Tuy nhiên, trong quá trình nghiên cứu, chúng tôi đã phát hiện ra hai
cách để thêm hỗ trợ Conditional UI cho ứng dụng iOS, vì trải nghiệm
người dùng cũng sẽ khác nhau.

**Loại A: Lớp phủ (Overlay) / Cửa sổ bật lên (Popup) trên Hầu hết Toàn bộ Màn hình**

Loại A đầu tiên hiển thị một lớp phủ / cửa sổ bật lên kéo dài hầu hết trên toàn bộ màn hình. Tại đây,
bạn sẽ thấy tất cả các passkey có sẵn đối với bên phụ thuộc này. Một
ví dụ nổi bật triển khai Conditional UI theo cách này là
KAYAK. Lớp phủ / cửa sổ bật lên tự động hiện ra khi người dùng
mở đúng màn hình.

![Conditional UI iOS App Popup](https://www.corbado.com/website-assets/65fd93a0a95c16b286ab7bc1_conditional_ui_ios_app_popup_00d4f8124a.jpg)

**Loại B: Tự động điền trên Bàn phím (Keyboard Autofill)**

Loại B thứ hai hiển thị một passkey phù hợp trong phần tự động điền của bàn phím
(nơi các mật khẩu cũng được đề xuất để tự động điền). Nhấp vào giá trị được đề xuất sẽ
thực hiện xác thực Face ID và cho phép bạn đăng nhập. Trong
phiên bản ứng dụng iOS hiện tại của bảng điều khiển dành cho nhà phát triển Corbado, chúng tôi đã triển khai theo cách này
(xem thông báo Sign in with passkey for `<relying party ID>` cùng với tên người dùng WebAuthn). Để hiển thị, người dùng cần chạm vào trường đầu vào:

![Conditional UI iOS app Keyboard Autofill](https://www.corbado.com/website-assets/65fd93ae3406831e812dcae2_conditional_ui_ios_app_keyboard_autofill_98e9550aab.jpg)

Tính năng tự động điền passkey trong phần bàn phím này có thể gặp sự cố khi iOS mới
được cài đặt vì dường như có một dạng bộ nhớ đệm (caching) diễn ra ở nền để tra cứu
tất cả các passkey khả dụng cho bên phụ thuộc này.

Nhấp vào biểu tượng chìa khóa ở bên phải của passkey được đề xuất sẽ dẫn đến giao diện quen thuộc
để chọn mật khẩu / passkey trong iOS:

![Conditional UI iOS app Keyboard Autofill Details](https://www.corbado.com/website-assets/65fd952b9e058d8bf2ae011c_conditional_ui_ios_app_keyboard_autofill_details_582133a5e0.jpg)

Xin lưu ý rằng chúng tôi chưa tìm thấy tài liệu chính thức, và những hiểu biết của chúng tôi dựa trên
kinh nghiệm và giả thuyết của chúng tôi thay vì bằng chứng cụ thể về cách triển khai thích hợp.

#### 6.6.2 Conditional UI trong Ứng dụng Android

Trong Android, câu chuyện về Conditional rõ ràng hơn một chút,
vì chỉ có một dạng cho Conditional UI / tự động điền passkey tận dụng
API Credential Manager của Android (xem
tài liệu [tại đây](https://developer.android.com/training/sign-in/passkeys)). Bởi vì
các nhà cung cấp Android có thể khác nhau, hãy theo dõi các
lỗi passkey của Credential Manager tách biệt với các mẫu lỗi WebAuthn
chỉ dành cho trình duyệt.

Mở trang nơi Conditional UI được triển khai sẽ hiển thị màn hình sau, nơi
bạn sẽ tìm thấy các cách khác nhau để đăng nhập:

![Conditional UI Android app ](https://www.corbado.com/website-assets/65fd953866efb99383ecadff_conditional_ui_android_app_d9744622dc.jpg)

Nhấp vào **More saved sign-ins** cung cấp thêm nhiều tùy chọn để chọn cho việc đăng nhập
(bao gồm xác thực chéo thiết bị và lựa chọn một nền tảng đồng bộ passkey
khác, ví dụ: Samsung Pass hoặc
1Password):

![Conditional UI Android app details](https://www.corbado.com/website-assets/65fd954176d4bacee21bd397_conditional_ui_android_app_details_bb2b567121.jpg)

## 7. Ví dụ về Conditional UI trong Các Thiết bị / Trình duyệt Khác nhau

Để minh họa Conditional UI trông như thế nào đối với người dùng cuối, chúng tôi đã thêm một số ảnh chụp màn hình
về menu tự động điền Conditional UI bằng cách sử dụng [https://passkeys.eu](https://passkeys.eu).

### 7.1 Conditional UI trên Windows 11 (22H2) + Chrome 118

![Conditional UI Windows Chrome](https://www.corbado.com/website-assets/653274d5f112bcb90551666f_conditional_ui_windows_chrome_f6be9c714b.png)

### 7.2 Conditional UI trên macOS Ventura (13.5.1) + Chrome 118

![Conditional UI macOS Chrome](https://www.corbado.com/website-assets/653274ef4711bafab8f9337e_conditional_ui_macos_chrome_b577291109.png)

### 7.3 Conditional UI trên macOS Ventura (13.5.1) + Safari 16.6

![Conditional UI macOS Safari](https://www.corbado.com/website-assets/6532750a0dd891b360beef99_conditional_ui_macos_safari_e27787adb9.png)

### 7.4 Conditional UI trên Android 13 + Chrome 118

![Conditional UI Android Chrome](https://www.corbado.com/website-assets/6532752344d30f53cb09b9b6_conditional_ui_android_chrome_25ff68bcb5.jpg)

### 7.5 Conditional UI trên iOS 17.1 + Safari 17.1

![Conditional UI iOS Safari](https://www.corbado.com/website-assets/65327537f112bcb90551b96b_conditional_ui_ios_safari_87cd12b54e.PNG)

## 8. Conditional UI trong Các Trường hợp Đặc biệt (Edge Cases)

Hãy cùng xem xét một số kịch bản phổ biến trong các ứng dụng thực tế.

### 8.1 Conditional UI nếu không có Passkey nào

Nếu không có passkey nào được lưu cho một trang web, Conditional UI sẽ hoạt động khác nhau tùy thuộc
vào trình duyệt và hệ điều hành.

#### 8.1.1 Conditional UI không có Passkey trên Chrome đối với macOS

Trên **Chrome dành cho macOS**, nhấp vào trường đầu vào sẽ hiển thị một menu thả xuống tự động điền trống:

![conditional ui no passkey macos chrome](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_no_passkey_macos_chrome_8cb107283f.png)

#### 8.1.2 Conditional UI không có Passkey trên Safari đối với macOS

Trên **Safari dành cho macOS**, không có menu thả xuống nào được hiển thị - chỉ có một biểu tượng nhỏ mờ nhạt trong trường đầu vào:

![conditional ui no passkey macos safari](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_no_passkey_macos_safari_1be2b7f264.png)

#### 8.1.3 Conditional UI không có Passkey trên Android hoặc iOS

Trên **Android hoặc iOS**, giao diện tự động điền chỉ xuất hiện nếu người dùng chạm vào trường
đầu vào và hệ điều hành tìm thấy các thông tin xác thực phù hợp.

Sự biến đổi này là có chủ ý và là một phần của mô hình quyền riêng tư của WebAuthn: các trang web không thể
phát hiện xem người dùng có passkey hay không trừ khi người dùng chủ động chọn một.

### 8.2 Conditional UI và Nhiều Trình quản lý Thông tin xác thực / Nhà cung cấp Passkey

Nếu một người dùng cài đặt nhiều nhà cung cấp passkey (ví dụ:
iCloud Keychain,
Google Password Manager,
1Password), trình duyệt hoặc hệ điều hành sẽ
thường mặc định chọn trình quản lý thông tin xác thực chính của người dùng.

Để biết danh sách các nhà cung cấp passkey / trình quản lý thông tin xác thực
khác nhau hỗ trợ passkey, chúng tôi khuyên bạn nên xem qua
[liên kết GitHub](https://passkeydeveloper.github.io/passkey-authenticator-aaguids/explorer/) sau đây.

#### 8.2.1 Conditional UI và Nhiều Trình quản lý Thông tin xác thực trên Android

Trên Android, Credential Manager cho thấy các nhà cung cấp khác nhau như
Samsung Pass hoặc
1Password.

1. Khi nhấp vào trường đầu vào số nhận dạng người dùng, menu này sẽ hiện ra nơi người dùng có thể
   chọn một passkey.

![conditional ui multiple credential managers android choose passkey](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_multiple_credential_managers_android_choose_passkey_1f5be7736f.png)

2. Nếu người dùng nhấp vào "More passkeys" ở màn hình trước, một lựa chọn hiển thị trước của các
   nhà cung cấp passkey / trình quản lý thông tin xác thực khác và passkey sẽ
   xuất hiện:

![conditional -ui multiple credential managers android choose sign in](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_multiple_credential_managers_android_choose_sign_in_d91c861fca.png)

3. Nếu người dùng nhấp vào "More saved sign-ins" ở màn hình trước, một danh sách toàn bộ các thông tin đăng nhập
   khả dụng sẽ xuất hiện, nơi người dùng có thể chọn một passkey.

![conditional ui multiple credential managers android choose sign in details](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_multiple_credential_managers_android_choose_sign_in_details_e9d9526da9.png)

#### 8.2.2 Conditional UI và Nhiều Trình quản lý Thông tin xác thực trên iOS

Trên iOS, biểu tượng chìa khóa sẽ mở danh sách đầy đủ các passkey từ nhiều nguồn khác nhau.

1. Đầu tiên, trên iOS 18+,
   Conditional UI thông thường với nhà cung cấp passkey mặc định sẽ xuất hiện.

![conditional ui multiple credential managers ios](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_multiple_credential_managers_ios_4c1fd3eaa7.png)

2. Khi nhấp vào biểu tượng bàn phím, menu lựa chọn sau sẽ hiển thị.

![conditional ui multiple credential managers ios select provider](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_multiple_credential_managers_ios_select_provider_737870e35b.png)

3. Sau khi chọn một trình quản lý thông tin xác thực / nhà cung cấp passkey,
   người dùng có thể chọn passkey để sử dụng.

![conditional ui multiple credential managers ios select passkey](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/conditional_ui_multiple_credential_managers_ios_select_passkey_568b192b3f.png)

> Là một ứng dụng hoặc trang web, bạn không thể kiểm soát trình quản lý thông tin xác thực nào được sử dụng - hệ điều hành
> quản lý lựa chọn đó để bảo vệ
> quyền riêng tư của người dùng.

## 9. Kết luận

Passkey, với khả năng Conditional UI / tự động điền passkey, là phương pháp xác thực
trực tuyến mới. Khi chúng ta chuyển sang một kỷ nguyên nơi mật khẩu ngày càng được thay thế
nhiều hơn bởi passkey, nhu cầu về các cơ chế chuyển đổi mạnh mẽ và thân thiện với người dùng là không thể phủ nhận.
Bài viết này đã giúp hiểu cách triển khai Conditional UI một cách chính xác, một sự trợ giúp
tuyệt vời trong quá trình chuyển đổi và những khía cạnh nào cần đặc biệt lưu ý.

## Những Câu hỏi Thường gặp

### Làm thế nào để kiểm tra xem trình duyệt có hỗ trợ Conditional UI hay không trước khi bắt đầu luồng tự động điền passkey?

Gọi `PublicKeyCredential.isConditionalMediationAvailable()` và chỉ tiếp tục nếu
nó trả về true. Kiểm tra này ngăn chặn các lỗi hiển thị cho người dùng trên các sự kết hợp trình duyệt và thiết bị
không được hỗ trợ. Phương thức này nên được đánh giá trên mỗi lần tải trang trước khi gọi
`navigator.credentials.get()` với `mediation: "conditional"`.

### Tại sao Conditional UI chỉ hoạt động với thông tin xác thực có thể khám phá mà không phải là tất cả các passkey?

Trình xác thực chỉ lưu trữ dữ liệu dành riêng cho người dùng chẳng hạn như tên và tên hiển thị đối với khóa
thường trú (thông tin xác thực có thể khám phá). Các khóa không thường trú không giữ lại thông tin này, vì vậy
menu tự động điền không thể điền các thông tin chi tiết về tài khoản để người dùng lựa chọn.

### Điều gì xảy ra trong Conditional UI khi người dùng không có passkey được đăng ký cho một trang web?

Hành vi thay đổi tùy theo nền tảng. Chrome trên macOS hiển thị một menu thả xuống tự động điền trống, Safari trên
macOS chỉ hiển thị một biểu tượng mờ nhạt trong trường đầu vào và trên Android hoặc iOS, giao diện tự động điền
chỉ xuất hiện nếu hệ điều hành tìm thấy thông tin xác thực phù hợp sau khi người dùng chạm vào trường đó.
Sự khác biệt này là cố ý và nằm trong một phần của mô hình quyền riêng tư của WebAuthn: các trang web không thể
phát hiện xem passkey có tồn tại hay không trừ khi người dùng chủ động chọn một.

### Làm cách nào để hủy yêu cầu Conditional UI đang diễn ra khi người dùng chuyển sang phương thức đăng nhập bằng passkey thông thường?

Tạo một `AbortController` ở phạm vi toàn cục và truyền tín hiệu (signal) của nó cho
`navigator.credentials.get()`. Gọi `.abort()` trên bộ điều khiển (controller) khi người dùng khởi tạo
luồng đăng nhập bằng phương thức (modal). Luôn khởi tạo (instantiate) một `AbortController` mới mỗi khi Conditional UI
khởi động lại, bởi vì việc sử dụng lại một bộ điều khiển đã bị hủy sẽ dẫn đến việc hủy ngay lập tức
yêu cầu WebAuthn.

### Conditional UI có hoạt động trong các ứng dụng iOS và Android gốc không hay chỉ hoạt động trong trình duyệt web?

Conditional UI hoạt động trong cả ứng dụng iOS và Android gốc. iOS hỗ trợ hai biến thể: một
cửa sổ bật lên (popup) lớp phủ toàn màn hình và một gợi ý tự động điền trên bàn phím. Android sử dụng API Credential
Manager, có thể hiển thị passkey từ nhiều nhà cung cấp khác nhau như Samsung Pass hoặc
1Password.
