Эта страница переведена автоматически. Прочитайте оригинальную версию на английском здесь.

Шпаргалка по Passkeys. Практические рекомендации, шаблоны внедрения и KPI для программ passkeys.
isConditionalMediationAvailable() необходимо вызывать перед запуском любого процесса Conditional UI, чтобы предотвратить видимые пользователю ошибки в неподдерживаемых браузерах или на устройствах.autocomplete="username webauthn" в поле ввода HTML дает сигнал браузеру показывать ключи доступа вместе с предложениями паролей в выпадающем меню автозаполнения.mediation: "conditional" в вызове navigator.credentials.get() активирует автозаполнение ключей доступа без прерывания пользователей блокирующим модальным диалогом.AbortController требуется для отмены текущих запросов Conditional UI, поскольку выпадающие меню автозаполнения, в отличие от модальных окон, не имеют встроенной кнопки отмены.С быстрым внедрением ключей доступа (и лежащего в их основе протокола WebAuthn) аутентификация стала более безопасной и удобной для многих пользователей. Одним из выдающихся достижений ключей доступа стала интеграция Conditional UI, часто называемого "автозаполнением ключей доступа" (passkey autofill) или Conditional Mediation (далее мы будем использовать термин Conditional UI).
Несмотря на недавнее появление и продолжающееся внедрение в браузерах, наблюдается заметный пробел в технической документации и советах по реализации Conditional UI. Эта статья призвана восполнить этот пробел, объяснив, что такое Conditional UI, как он работает и как справляться с типичными проблемами при его реализации.
Последние статьи
⚙️
Шпаргалка для разработчиков по ключам доступа (passkeys)
👤
Как удалить ключ доступа на Apple, Windows и Android
📖
Техническое объяснение Conditional UI (автозаполнение ключей доступа) для WebAuthn
📖
Полное руководство по ошибкам WebAuthn в рабочей среде (2026)
📖
Ключи доступа в Brave Browser (2026): что работает, а что ломается
Conditional UI представляет собой новый режим для процессов входа с помощью ключей доступа / WebAuthn. Он выборочно отображает ключи доступа в пользовательском интерфейсе (UI) только тогда, когда у пользователя есть обнаруживаемые учетные данные (резидентный ключ), которые являются типом ключа доступа, зарегистрированным у проверяющей стороны (онлайн-сервиса) и сохраненным в аутентификаторе его устройства (например, ноутбука, смартфона). Ключи доступа отображаются в выпадающем меню выбора, которое смешивается с автозаполняемыми паролями, обеспечивая плавный переход между традиционными системами паролей и расширенной аутентификацией с помощью ключей доступа, поскольку пользователи видят и то, и другое в одном контексте. Этот интеллектуальный подход гарантирует, что пользователи не будут перегружены ненужными опциями и смогут проходить процесс входа более легко.
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 studyОснова Conditional UI базируется на трех главных принципах:
Подпишитесь на наш Passkeys Substack, чтобы получать новости.
Далее мы приводим пошаговый разбор отдельных этапов всего процесса Conditional UI:
В целом, процесс Conditional UI можно разделить на две фазы. На этапе загрузки страницы логика Conditional UI выполняется в фоновом режиме, в то время как на этапе действий пользователя пользователь должен активно что-то сделать.
isConditionalMediationAvailable(), чтобы определить, поддерживает ли текущая комбинация браузера / устройства Conditional UI. Процесс продолжается только в том случае, если ответ положительный, в противном случае процесс Conditional UI прерывается.credentials.get() с полученными PublicKeyCredentialRequestOptions и свойством mediation, установленным как conditional (условное), запускает процесс локальной аутентификации на устройстве.Следуя этому процессу, Conditional UI предлагает бесшовный и удобный интерфейс аутентификации.
Для работы Conditional UI необходимо учитывать некоторые общие аспекты:
Присоединяйтесь к нашему Passkeys Community для обновлений и поддержки.
Для работы Conditional UI на стороне клиента должны быть выполнены следующие требования:
isConditionalMediationAvailable() и проверять техническую доступность Conditional UI (см. ниже для получения более подробной информации).Для работы Conditional UI также должны быть выполнены некоторые требования на стороне сервера:
С момента официального выпуска Conditional UI в конце 2022 года и более ранних бета-версий мы активно тестировали его и работали с ним. Далее мы хотим поделиться с вами практическими советами, которые помогли во время внедрения Conditional UI.
Экспериментируйте с passkey-флоу в Passkeys Debugger.
Полный минималистичный пример кода для метода Conditional UI будет выглядеть так:
<!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>
Реализуйте обнаружение Conditional UI, которое гарантирует, что Conditional UI используется только тогда, когда текущая комбинация устройства / браузера поддерживает его. Это должно работать без отображения видимых пользователю ошибок при отсутствии поддержки Conditional UI. Включение метода isConditionalMediationAvailable() в пользовательский интерфейс решает эту проблему. Если поддержка Conditional UI обеспечена, можно запустить процесс входа с помощью Conditional UI.
// 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", }); /* ... */ } }
Поле ввода должно получить HTML-токен автозаполнения webauthn. Это сигнализирует клиенту о необходимости подставлять ключи доступа в текущий запрос. Помимо ключей доступа, могут отображаться и другие значения автозаполнения. Эти токены автозаполнения можно комбинировать с другими существующими токенами, например:
autocomplete="username webauthn": Помимо отображения ключей доступа, это также предлагает автозаполнение имени пользователя.autocomplete="current-password webauthn": Помимо отображения ключей доступа, это также предлагает автозаполнение пароля.<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" />
Для получения дополнительных сведений мы рекомендуем прочитать этот пост в блоге, в котором содержится более подробная информация о токенах автозаполнения / автодополнения для ключей доступа и паролей.
Чтобы получить доступные ключи доступа после получения объекта PublicKeyCredentialRequestOptions, следует вызвать функцию navigator.credentials.get() (которая обслуживает как ключи доступа, так и пароли). Объект PublicKeyCredentialRequestOptions должен иметь параметр mediation, установленный в значение conditional, чтобы активировать Conditional UI на клиенте. В случаях, когда вам вместо этого нужен модальный запрос ключа доступа, см. немедленное опосредование (immediate mediation).
const credential = await navigator.credentials.get({ publicKey: options.publicKeyCredentialRequestOptions, mediation: "conditional", });
Если доступного ключа доступа нет, или пользователь игнорирует предложенные ключи доступа и вводит свой адрес электронной почты, процесс Conditional UI останавливается. Это подчеркивает важность постоянной поддержки стандартного входа с помощью ключа доступа / WebAuthn через модальное окно.
Критически важный момент, на который следует обратить внимание, — это потенциальная необходимость остановки текущего запроса Conditional UI. В отличие от модальных окон, в выпадающих меню автозаполнения нет кнопки отмены. Согласно дизайну WebAuthn, в любой момент времени должен выполняться только один активный запрос учетных данных. Стандарт WebAuthn предлагает использовать AbortController для отмены процесса WebAuthn, применимого как к обычным процессам входа, так и к процессам входа с использованием Conditional UI (см. здесь для получения подробной информации).
В производственной телеметрии этот путь отмены часто является ожидаемым результатом потока управления, а не сбоем системы. Если вы видите большие объемы ошибок, вам необходимо классифицировать ожидаемые и неожидаемые случаи по типу операции и времени, прежде чем рассматривать их как регрессии (см. ошибки WebAuthn).
Процесс входа в Conditional UI активируется, как только пользователь заходит на страницу. Первоначальной задачей должно стать создание объекта AbortController с глобальной областью видимости. Это будет служить сигналом для вашего клиента о прекращении запроса автозаполнения, особенно если пользователь решит выполнить обычный процесс входа с помощью ключа доступа.
Убедитесь, что AbortController может быть вызван другими функциями и сбрасывается, если процесс Conditional UI необходимо перезапустить. Используйте свойство signal в вызове navigator.credentials.get(), включив ваш сигнал AbortController в качестве его значения. Это сигнализирует функции ключа доступа / WebAuthn о том, что запрос должен быть остановлен, если сигнал будет прерван. Не забывайте создавать новый AbortController каждый раз при запуске Conditional UI. Использование уже отмененного AbortController приведет к мгновенной отмене функции ключа доступа / WebAuthn. Оставшиеся шаги совпадают с обычным процессом входа с помощью ключа доступа. Ниже вы видите пример кода упомянутых шагов:
<!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>
При отсутствии поддержки Conditional UI направьте пользователей к обычному процессу входа с помощью ключа доступа. Предоставление этого пути важно для пользователей, полагающихся на аппаратные ключи безопасности (например, YubiKey), или тех, кто вынужден использовать нерезидентные ключи / необнаруживаемые учетные данные из-за ограничений аутентификатора.
Посмотрите, сколько людей действительно используют passkeys.
Если вы разрабатываете нативное приложение, например для iOS или Android, Conditional UI также работает. Не имеет значения, реализуете ли вы его нативно на Flutter, Kotlin или Swift, или решите использовать Chrome Custom Tabs CCT или SFSafariViewController или SFAuthenticationSession / ASWebAuthenticationSession. Оба подхода поддерживают Conditional UI.
В целом, мы не нашли почти никакой документации о том, как реализовать поддержку Conditional UI для приложений iOS. Однако во время нашего исследования мы обнаружили два способа добавить поддержку Conditional UI в приложение iOS, поскольку пользовательский опыт также будет различаться.
Тип A: Оверлей / всплывающее окно почти на весь экран
Первый тип A показывает оверлей / всплывающее окно, которое занимает почти весь экран. Здесь вы увидите все доступные ключи доступа для этой проверяющей стороны. Известным примером, реализующим Conditional UI таким образом, является KAYAK. Оверлей / всплывающее окно появляется автоматически, когда пользователь открывает нужный экран.
Тип B: Автозаполнение клавиатуры
Второй тип B отображает подходящий ключ доступа в разделе автозаполнения клавиатуры (где также предлагаются пароли для автозаполнения). Нажатие на предложенное значение выполнит аутентификацию Face ID и позволит вам войти в систему. В текущей версии приложения iOS панели разработчика Corbado мы реализовали это таким образом (см. сообщение Войти с помощью ключа доступа для <идентификатор проверяющей стороны> вместе с именем пользователя WebAuthn). Чтобы оно появилось, пользователю нужно коснуться поля ввода:
Эта функция автозаполнения ключей доступа в разделе клавиатуры может иметь проблемы при свежей установке iOS, так как по-видимому в фоновом режиме происходит некое кэширование, которое ищет все доступные ключи доступа для этой проверяющей стороны.
Нажатие на значок ключа справа от предложенного ключа доступа ведет на знакомый сайт для выбора паролей / ключей доступа в iOS:
Пожалуйста, обратите внимание, что мы не нашли официальной документации, и наши выводы основаны на нашем опыте и гипотезах, а не на конкретных доказательствах правильной реализации.
В Android история с Conditional UI немного яснее, так как существует только один тип для Conditional UI / автозаполнения ключей доступа, который использует Credential Manager API Android (см. документацию здесь). Поскольку провайдеры Android могут различаться, отслеживайте ошибки ключей доступа Credential Manager отдельно от шаблонов сбоев WebAuthn, относящихся только к браузеру.
При открытии страницы, где реализован Conditional UI, отображается следующий экран, где вы найдете различные способы входа в систему:
Нажатие на More saved sign-ins (Больше сохраненных входов) предоставляет больше возможностей для выбора входа в систему (включая аутентификацию на нескольких устройствах и выбор другой платформы синхронизации ключей доступа, например, Samsung Pass или 1Password):
Чтобы проиллюстрировать, как Conditional UI выглядит для конечного пользователя, мы добавили несколько скриншотов меню автозаполнения Conditional UI, используя https://passkeys.eu.
Попробуйте passkeys в live demo.
Давайте рассмотрим некоторые распространенные сценарии в реальных приложениях.
Если для сайта не сохранен ключ доступа, Conditional UI будет вести себя по-разному в зависимости от браузера и ОС.
В Chrome на macOS клик по полю ввода показывает пустое выпадающее меню автозаполнения:
В Safari на macOS выпадающее меню не отображается - только небольшой значок в поле ввода:
На Android или iOS интерфейс автозаполнения появляется только в том случае, если пользователь касается поля и ОС находит совпадающие учетные данные.
Эта вариативность преднамеренна и является частью модели конфиденциальности WebAuthn: веб-сайты не могут определить, есть ли у пользователя ключ доступа, пока пользователь активно его не выберет.
Если у пользователя установлено несколько провайдеров ключей доступа (например, iCloud Keychain, Google Password Manager, 1Password), браузер или ОС обычно по умолчанию используют основной менеджер учетных данных пользователя.
Для получения списка различных провайдеров ключей доступа / менеджеров учетных данных, поддерживающих ключи доступа, мы рекомендуем ознакомиться со следующей ссылкой на GitHub.
На Android Credential Manager предоставляет различных провайдеров, таких как Samsung Pass или 1Password.
На iOS значок ключа открывает полный список ключей доступа из различных источников.
Как приложение или веб-сайт, вы не можете контролировать, какой менеджер учетных данных используется - ОС управляет этим выбором для сохранения конфиденциальности пользователя.
Ключи доступа, с их возможностью Conditional UI / автозаполнения ключей доступа, являются новым способом онлайн-аутентификации. По мере нашего перехода к эпохе, когда пароли все больше и больше заменяются ключами доступа, потребность в надежных и удобных механизмах перехода неоспорима. Эта статья помогла понять, как правильно реализовать Conditional UI, что является большим подспорьем в процессе перехода, и на какие аспекты следует обратить особое внимание.
Corbado — это Authentication Intelligence Platform для CIAM-команд, обеспечивающих аутентификацию пользователей в крупных масштабах. Мы показываем то, что не видят логи IDP и общие инструменты аналитики: какие устройства, версии ОС, браузеры и менеджеры учётных данных поддерживают passkey, почему регистрации не превращаются в логины, где сбоит WebAuthn-поток и когда обновление ОС или браузера тихо ломает вход — всё это без замены Okta, Auth0, Ping, Cognito или вашего собственного IDP. Два продукта: Corbado Observe добавляет наблюдаемость для passkey и любых других способов входа. Corbado Connect даёт managed passkey со встроенной аналитикой (рядом с вашим IDP). VicRoads использует passkey для более чем 5 млн пользователей с Corbado (+80 % активации passkey). Поговорить с экспертом по passkey →
Вызовите PublicKeyCredential.isConditionalMediationAvailable() и продолжайте только в том случае, если функция возвращает true. Эта проверка предотвращает видимые пользователю ошибки на неподдерживаемых комбинациях браузеров и устройств. Метод следует вызывать при каждой загрузке страницы перед вызовом navigator.credentials.get() с параметром mediation: "conditional".
Аутентификаторы хранят пользовательские данные, такие как имя и отображаемое имя, только для резидентных ключей (обнаруживаемых учетных данных). Нерезидентные ключи не сохраняют эту информацию, поэтому меню автозаполнения не может подставить данные учетной записи для выбора пользователем.
Поведение зависит от платформы. Chrome на macOS показывает пустое выпадающее меню автозаполнения, Safari на macOS показывает лишь небольшой значок в поле ввода, а на Android или iOS интерфейс автозаполнения появляется, только если ОС находит подходящие учетные данные после того, как пользователь касается поля. Такая вариативность преднамеренна и является частью модели конфиденциальности WebAuthn: веб-сайты не могут определить, существует ли ключ доступа, пока пользователь активно его не выберет.
Создайте AbortController с глобальной областью видимости и передайте его сигнал в navigator.credentials.get(). Вызовите .abort() на контроллере, когда пользователь инициирует модальный процесс входа. Всегда создавайте новый AbortController каждый раз при перезапуске Conditional UI, поскольку повторное использование уже отмененного контроллера вызывает немедленную отмену запроса WebAuthn.
Conditional UI работает как в нативных приложениях iOS, так и Android. iOS поддерживает два варианта: всплывающее окно на весь экран и предложение автозаполнения на клавиатуре. В Android используется Credential Manager API, который может отображать ключи доступа от нескольких провайдеров, таких как Samsung Pass или 1Password.
Похожие статьи
Содержание