---
url: 'https://www.corbado.com/ru/blog/webauthn-relying-party-id-rpid-passkeys'
title: 'Идентификатор проверяющей стороны WebAuthn (rpID) и ключи доступа: домены и нативные приложения'
description: 'В этой статье объясняется идентификатор проверяющей стороны (Relying Party ID) WebAuthn для аутентификации по ключам доступа. Рассматривается правильная настройка, сопоставление доменов и конфигурации нативных приложений.'
lang: 'ru'
author: 'Vincent Delitz'
date: '2026-06-15T13:57:54.603Z'
lastModified: '2026-06-16T06:07:13.771Z'
keywords: 'идентификатор проверяющей стороны, relying party id, webauthn, ключи доступа, passkeys, нативные приложения'
category: 'WebAuthn Know-How'
---

# Идентификатор проверяющей стороны WebAuthn (rpID) и ключи доступа: домены и нативные приложения

## Key Facts

- **Идентификатор проверяющей стороны (Relying Party ID)** — это домен, встроенный в
  каждый ключ доступа. Аутентификация завершается неудачей, если источник браузера не
  совпадает, что делает ключи доступа надежно защищенными от фишинга.
- **RP ID** не должен находиться в **Списке публичных суффиксов (Public Suffix List)**, а
  его изменение делает недействительными все существующие ключи доступа. По умолчанию
  используйте корневой домен с прицелом на будущее.
- Для приложений iOS требуется файл **apple-app-site-association** в каталоге
  `/.well-known/` в рамках RP ID. Для Android требуется **assetlinks.json** по тому же
  пути. Кэширование новых файлов может занять до 24 часов.
- Для нескольких корневых доменов требуются **запросы связанных источников (Related Origin
  Requests)** через `.well-known/webauthn` для совместного использования ключей доступа.
  Используйте единый сервер WebAuthn с одним RP ID для всех приложений, как веб, так и
  нативных.

## 1. Введение

Аутентификация с помощью ключей доступа (passkeys) быстро становится нормой по мере того,
как технологические гиганты, такие как [TikTok](https://www.corbado.com/blog/tiktok-passkeys), GitHub,
[WhatsApp](https://www.corbado.com/blog/whatsapp-passkeys), X (Twitter), [LinkedIn](https://www.corbado.com/blog/linkedin-passkeys) и
Amazon, внедряют их или уже сделали это. Очевидно, что технологический мир признает
важность простой и безопасной аутентификации.

Помимо удобства аутентификации с помощью [Face ID](https://www.corbado.com/faq/is-face-id-passkey), Touch ID или
[Windows Hello](https://www.corbado.com/glossary/windows-hello), ключи доступа обеспечивают беспрецедентную
безопасность по сравнению с традиционными методами, такими как пароли. Одной из выдающихся
особенностей является их надежная защита от фишинга.

Фишинговая атака — это атака, при которой жертву обманом заставляют предоставить учетные
данные поддельному сайту, имитирующему оригинальный. Например, представьте, что вы
получаете электронное письмо, похожее на сообщение от вашего банка, с просьбой войти в
систему. Вы нажимаете на ссылку, и веб-сайт выглядит легитимным, поэтому вы вводите свои
учетные данные, и злоумышленник может использовать их для входа на исходный сайт. Это
становится все более серьезной проблемой в цифровую эпоху, и даже крупные компании, такие
как
[Okta ](https://www.darkreading.com/application-security/okta-flaw-involved-mgm-resorts-breach-attackers-claim)(провайдер
аутентификации!) или [Retool ](https://retool.com/blog/mfa-isnt-mfa/), стали жертвами
целевых фишинговых атак (spear-[phishing](https://www.corbado.com/glossary/phishing) — особая форма фишинга, при
которой на конкретных жертв направлены узкоспециализированные фишинговые уловки), что
подчеркивает необходимость надежных мер безопасности.

Напротив, если вы используете ключ доступа, а сайт является подделкой, аутентификация
завершится ошибкой. Это связано с тем, что ключи доступа привязаны к доменам, для которых
они были созданы, через **идентификатор проверяющей стороны (Relying Party ID)**.

> Вы не можете войти в систему с ключом доступа на любом другом сайте, что делает ключи
> доступа надежно защищенными от фишинга (хотя ни одна система не имеет абсолютного
> иммунитета ко всем векторам атак).

Этот механизм встроен в WebAuthn, базовый веб-стандарт для аутентификации без пароля.
WebAuthn строится на двух основных процедурах: регистрации и аутентификации.

Во время процедуры регистрации (sign-up) создается новый ключ доступа для онлайн-сервиса
(проверяющей стороны) через веб- или нативное приложение. В ходе этого процесса домен
(Relying Party ID), для которого создается ключ доступа, сохраняется в самом ключе.

Это позволяет процедуре аутентификации (login) проверять, совпадает ли онлайн-сервис
(проверяющая сторона), к которому относится веб- или нативное приложение, с
идентификатором проверяющей стороны, хранящимся в ключах доступа.

Далее мы подробно рассмотрим, как работает этот процесс
[сопоставления доменов](#what-relying-party-id) и как, в частности, защищаются нативные
приложения.

## 2. Что такое идентификатор проверяющей стороны?

[**Идентификатор проверяющей стороны (Relying Party ID)**](https://www.w3.org/TR/webauthn-2/#relying-party-identifier)
— это, по сути, домен, хранящийся в ключе доступа и гарантирующий, что ключ доступа будет
работать только в том случае, если текущий URL-адрес браузера (источник пользователя,
который автоматически отправляется с каждым запросом) совпадает с ним (см. подход с
нативными приложениями [ниже](#integration-options-native-apps)). Это важнейший компонент
спецификации WebAuthn, с которой вы можете ознакомиться
[здесь](https://www.w3.org/TR/webauthn-2/). Идентификатором проверяющей стороны может быть
корневой домен (например, `corbado.com`) или поддомен (`auth.corbado.com`). Вы не можете
сохранить корневой домен в качестве [Relying Party](https://www.corbado.com/glossary/relying-party) ID, если он
находится в Списке публичных суффиксов (найдите список и библиотеки для определения
публичных суффиксов [здесь](https://publicsuffix.org/learn/)). Изменение
[Relying Party](https://www.corbado.com/glossary/relying-party) ID для онлайн-сервиса приведет к нарушению работы
существующих ключей доступа (исключения: новый [Relying Party](https://www.corbado.com/glossary/relying-party) ID
является поддоменом старого Relying Party ID, или настроены запросы связанных источников
через `.well-known/webauthn`, чтобы разрешить повторное использование ключей доступа между
связанными доменами).

В процессе аутентификации Relying Party ID сверяется с URL-адресом браузера (источником
пользователя), чтобы убедиться в их совпадении. Совпадение в этом смысле означает, что
либо:

- URL-адрес браузера (источник пользователя) точно совпадает с Relying Party ID, ИЛИ
- URL-адрес браузера (источник пользователя) является поддоменом, соответствующим Relying
  Party ID, а родительский домен доступен для регистрации (например, `com` или любой домен
  из Списка публичных суффиксов не подойдут).

Вот подробная схема того, какой _originalHost_ (второй столбец) имеет доступ к своему
родительскому домену:

![relying party id table](https://www.corbado.com/website-assets/relying_party_id_table_4c98cc04f4.jpg)

Ниже вы видите проанализированные параметры
[**PublicKeyCredentialCreationOptions**](https://www.w3.org/TR/webauthn-2/#iface-pkcredential):

```json
{
    "publicKey": {
        "attestation": "direct",
        "authenticatorSelection": {
            "authenticatorAttachment": "platform",
            "requireResidentKey": false,
            "userVerification": "preferred"
        },
        "challenge": "qNqrdXUrk5S7dCM1MAYH3qSVDXznb-6prQoGqiACR10=",
        "excludeCredentials": [],
        "pubKeyCredParams": [
            {
                "alg": -7,
                "type": "public-key"
            }
        ],
        "rp": {
            "id": "corbado.com",
            "name": "Corbado"
        },
        "timeout": 30000,
        "user": {
            "displayName": "Corbado user",
            "id": "bz9ZDfHzOBLycqISTAdWwWIZt8VO-6mT3hBNXS5jwmY="
        }
    }
}
```

`rp` означает Relying Party (проверяющая сторона).

Одним из главных преимуществ Relying Party ID является предотвращение фишинговых атак.
Представьте себе следующий сценарий:

1. Злоумышленник разрабатывает клон [PayPal](https://www.corbado.com/blog/paypal-passkeys) — поддельный веб-сайт,
   который пытается украсть ваши учетные данные [PayPal](https://www.corbado.com/blog/paypal-passkeys), чтобы
   войти в систему от вашего имени и перевести деньги на счет злоумышленника. Этот
   поддельный сайт [PayPal](https://www.corbado.com/blog/paypal-passkeys) размещен на домене paybal.com (поэтому
   на первый взгляд часто не видно, что это другой домен).
2. Ранее вы уже создали ключ доступа для легитимного сайта PayPal. В этом ключе доступа
   был сохранен Relying Party ID paypal.com.
3. Вы заходите на поддельный сайт PayPal по адресу paybal.com (поскольку вы посещаете этот
   сайт, источником вашего запроса является paybal.com\*), и сайт отправляет вашему
   устройству (аутентификатору) запрос (challenge) для Relying Party ID `paypal.com`
   (здесь он пытается вас обмануть) и просит подписать его вашим ключом доступа для
   Relying Party ID paypal.com.
4. Ваше устройство (аутентификатор) проверяет, совпадают ли источник запроса
   (`paybal.com`) и Relying Party ID, сохраненный в ключе доступа (`paypal.com`).
5. Поскольку они очевидно не совпадают, аутентификация завершается ошибкой, что спасает
   вас от предоставления злоумышленнику доступа к вашему аккаунту PayPal.

Следующая диаграмма иллюстрирует этот механизм предотвращения фишинга.

_В случае нативного приложения обработка источника (origin) зависит от платформы: На
Android источник имеет формат `android:apk-key-hash:<SHA256_fingerprint>`. На iOS
источником WebAuthn является веб-источник RP (например, `https://paypal.com`). В обоих
случаях доверие между вашим нативным приложением и сервером проверяется через
соответствующий файл ассоциации (см. [ниже](#configuring-relying-party-native-apps)).
Подробную информацию о том, как работает проверка источника для нативных приложений,
смотрите в нашем специальном руководстве по проверке источников WebAuthn для нативных
приложений._

## 3. Два различных варианта интеграции для нативных приложений

Для внедрения ключей доступа в нативное приложение разработчик может выбирать между
добавлением их через [WebView](https://www.corbado.com/blog/native-app-passkeys) или нативно. Давайте рассмотрим
преимущества и недостатки обоих подходов.

### 3.1 Интеграция ключей доступа через WebView

![Passkey Integration WebView (GitHub)](https://www.corbado.com/website-assets/650c601b1eb462e25702a870_android_webview_passkey_github_8bc81d9852.jpg)

Использование **WebView**\* для интеграции ключей доступа означает встраивание
веб-браузера в нативное приложение для управления процессом аутентификации. Этот подход,
по сути, отображает веб-страницу внутри приложения, что упрощает повторное использование
веб-потоков аутентификации без необходимости их переписывания для нативной платформы.
Однако есть и некоторые недостатки. [WebView](https://www.corbado.com/blog/native-app-passkeys) может не
поддерживать все функции ключей доступа, и существует потенциальный риск атак вида
«человек посередине», если интеграция реализована небезопасно. Кроме того,
пользовательский опыт может быть не таким плавным, как при нативной интеграции, и могут
возникнуть сложности с поддержанием единообразного поведения на разных устройствах и
версиях ОС.

_\*Существует несколько типов WebView: на iOS (WKWebView, SFSafariViewController или
SFAuthenticationSession / ASWebAuthenticationSession для потоков аутентификации на основе
OAuth/OpenID Connect) и Android (WebView, CCT-Chrome Custom Tabs). Подробности смотрите в
этой статье. Мы рекомендуем использовать SFSafariViewController/ASWebAuthenticationSession
и Chrome Custom Tabs в контексте ключей доступа, если вы не хотите использовать нативную
интеграцию._

### 3.2 Нативная интеграция ключей доступа

![Native Passkey Integration (Kayak)](https://www.corbado.com/website-assets/650c625cac723f594137a029_android_native_passkey_kayak_0f689e761e.jpg)

**Нативная интеграция** предполагает встраивание функциональности ключей доступа
непосредственно в приложение [iOS](https://www.corbado.com/blog/how-to-enable-passkeys-ios) или
[Android](https://www.corbado.com/blog/how-to-enable-passkeys-android) с использованием платформенно-зависимых
API и библиотек. Этот метод обеспечивает более бесшовный пользовательский опыт, так как
нет необходимости переходить между нативным приложением и
[WebView](https://www.corbado.com/blog/native-app-passkeys). Это также обеспечивает лучшую производительность и
более единообразный внешний вид. С точки зрения безопасности нативная интеграция может
обеспечить повышенную защиту от определенных типов атак, особенно в сочетании с
платформенно-зависимыми функциями безопасности. Однако трудозатраты на реализацию могут
быть выше, так как разработчикам нужно писать и поддерживать отдельный код для каждой
платформы (Android и [iOS](https://www.corbado.com/blog/how-to-enable-passkeys-ios)). Кроме того, чтобы быть в
курсе последних спецификаций ключей доступа / WebAuthn, может потребоваться более частое
обновление приложения.

В дальнейшем мы сосредоточимся на нативной интеграции ключей доступа.

## 4. Настройка проверяющей стороны для нативных приложений

Нативные приложения (например, приложения для [iOS](https://www.corbado.com/blog/how-to-enable-passkeys-ios) или
[Android](https://www.corbado.com/blog/how-to-enable-passkeys-android)) представляют собой более сложную задачу
по сравнению с веб-приложениями. В отличие от веб-приложений, здесь нет URL-адреса
браузера для сопоставления с идентификатором проверяющей стороны. Тем не менее, для
обеспечения того же уровня безопасности домены связываются с нативными приложениями с
помощью **файлов ассоциации**, чтобы установить доверие между доменом и нативным
приложением.

Это особенно важно, если ключ доступа был создан в веб-приложении и должен использоваться
для того же Relying Party ID в нативном приложении (и наоборот).

### 4.1 Файлы ассоциации в iOS: apple-app-site-association

iOS использует файл apple-app-site-association. Этот файл содержит различные права
(entitlements), но для WebAuthn и ключей доступа важно право webcredentials.

```json
{
    "webcredentials": {
        "apps": ["9RF9KY88B2.com.corbado.passkeys"]
    }
}
```

В `webcredentials.apps` вам нужно указать префикс идентификатора приложения (Application
Identifier Prefix, например `9RF9KY77B2`) и идентификатор бандла (Bundle Identifier,
например `com.corbado.passkeys`).

Чтобы нативные приложения iOS работали, файл apple-app-site-association должен храниться в
каталоге `/.well-known` идентификатора проверяющей стороны
(`https://<Relying Party ID>/.well-known/apple-app-site-association`).

Посмотрите рабочий пример
[здесь](https://pro-6244024196016258271.frontendapi.cloud.corbado.io/.well-known/apple-app-site-association).

### 4.2 Файлы ассоциации в Android: assetlinks.json

[Android](https://www.corbado.com/blog/how-to-enable-passkeys-android) использует файл `assetlinks.json`,
который, как и его аналог в iOS, требует особых настроек для WebAuthn и ключей доступа.

```json
[
    {
        "relation": [
            "delegate_permission/common.handle_all_urls",
            "delegate_permission/common.get_login_creds"
        ],
        "target": {
            "namespace": "android_app",
            "package_name": "com.corbado.passkeys.pub",
            "sha256_cert_fingerprints": [
                "F8:90:4E:9A:99:01:71:75:25:38:D5:36:16:2D:B3:65:EB:41:51:D4:53:9A:72:BC:4B:56:C5:16:43:62:E2:C0"
            ]
        }
    }
]
```

У вас должны быть заданы значения `relation`: `delegate_permission/common.handle_all_urls`
и `delegate_permission/common.get_login_creds`. Кроме того, вам нужно добавить имя пакета
и отпечаток SHA-256 вашего сертификата подписи.

Чтобы разрешить совместное использование ключа доступа между нативным приложением и
веб-приложением, вам нужно добавить две записи. Одну для пространства имен web и одну для
пространства имен android_app.

Посмотрите рабочий пример
[здесь](https://pro-6244024196016258271.frontendapi.cloud.corbado.io/.well-known/assetlinks.json).

Чтобы приложения Android работали, файл assetlinks.json должен храниться в каталоге
`/.well-known` идентификатора проверяющей стороны
(`https://<Relying Party ID>/.well-known/assetlinks.json` - то есть примерно так же, как в
iOS).

Ознакомьтесь с этой статьей в блоге, чтобы увидеть пример реализации, которая разделяет
ключи доступа между нативным приложением для Android/iOS и веб-приложением.

## 5. Установление доверия между нативным и веб-приложением

### 5.1 iOS

Процесс установления доверия между приложением iOS и веб-приложением выглядит следующим
образом:

1. Разработчик приложения для iOS должен указать список доменов, которые он хочет
   ассоциировать с нативным приложением. Эти домены жестко прописываются в правах
   (entitlements) приложения iOS, например:

- webcredentials:auth.Corbado.com
- webcredentials:\*.Corbado.com

2. Каждый раз, когда приложение iOS устанавливается или обновляется, iOS загружает файл
   apple-app-site-association для каждой записи из списка прав приложения.

3. Когда учетные данные (например, ключ доступа) создаются внутри приложения iOS,
   приложение проверяет, ассоциирован ли домен сервера проверяющей стороны с приложением,
   проверяя следующие два аспекта:

- Существует ли на устройстве файл `apple-app-site-association` для этого домена сервера
  проверяющей стороны?
- Указано ли приложение iOS в этом файле `apple-app-site-association`?

Если и только если на оба вопроса можно ответить «да», в приложении iOS может быть создан
ключ доступа.

### 5.2 Android

Процесс установления доверия между приложением Android и веб-приложением выглядит
следующим образом:

1. Разработчик приложения для Android должен указать список доменов, которые он хочет
   связать с приложением. Эти домены хранятся в качестве целевых (targets) с пространством
   имен web в файле assetlinks.json. Чтобы объявить, что приложения Android и
   веб-приложения делятся учетными данными, необходимо указать
   `delegate_permission/common.get_login_creds`. Подробности можно найти
   [здесь](https://developer.android.com/training/sign-in/passkeys#add-support-dal).

2. Если ключ доступа создается внутри приложения Android, приложение проверяет, связан ли
   Relying Party ID с приложением, просматривая файл `assetlinks.json`:

- Существует ли файл `assetlinks.json` для этого Relying Party ID по адресу
  `https://<Relying Party ID>./well-known/assetlinks.json`
- Правильно ли приложение Android определено в качестве цели.

3. Если и только если на оба вопроса можно ответить «да», в приложении Android может быть
   создан ключ доступа.

Диаграмма ниже сравнивает эти процессы установления доверия бок о бок.

## 6. Обзор настроек для Android, iOS и Flutter

Ниже мы приводим подробный обзор различных настроек, необходимых для правильной настройки
аутентификации по ключам доступа для нативных приложений.

| Функция                                                                         | iOS                                                                                                                                                             | Android                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Официальное руководство по реализации нативной аутентификации по ключам доступа | Apple Developer                                                                                                                                                 | Google Developer                                                                                                                                                                                                                                                                                                                                                                                                                     |
| Позволяет делиться ключами доступа с веб-приложениями                           | Да, через файл apple-app-site-association                                                                                                                       | Да, через assetlinks.json                                                                                                                                                                                                                                                                                                                                                                                                            |
| Расположение файла ассоциации                                                   | [https://acme.com/.well-known/apple-app-site-association](https://acme.com/.well-known/apple-app-site-association)                                              | [https://acme.com/.well-known/assetlinks.json](https://acme.com/.well-known/assetlinks.json)                                                                                                                                                                                                                                                                                                                                         |
| Кэширование файла                                                               | Да (начиная с iOS 14), первоначальная синхронизация может занять до 24 ч                                                                                        | Да (Play Services)                                                                                                                                                                                                                                                                                                                                                                                                                   |
| Возможен обход                                                                  | Да, с разделом alternate mode                                                                                                                                   | Нет                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| Тестируется с помощью                                                           | теста apple-app-site-association                                                                                                                                | теста assetlinks.json                                                                                                                                                                                                                                                                                                                                                                                                                |
| Идентификатор приложения с примером                                             | `<Application Identifier Prefix>.<Bundle Identifier>`, например `T84QZS65DQ.com.facebook.Messenger`                                                             | Отпечаток SHA256, например `E3:F9:E1:E0:CF:99:D0:E5:6A:05:5B:A6: 5E:24:1B:33:99: 7F:CE:A5:24:32: 6B:0C:DD:6E:C1:32: 7E:D0:FD:C1`                                                                                                                                                                                                                                                                                                     |
| Где найти идентификатор приложения                                              | Team Application Identifier Prefix можно найти в учетной записи разработчика на developer.apple.com, а Bundle Identifier — это точное название из проекта XCode | Когда уже загружено: Google Play Console &gt; Управление релизами &gt; Подпись приложения. Локально: `keytool -list -v -keystore <keystore path> -alias <key alias> -storepass <store password> -keypass <key password>`                                                                                                                                                                                                             |
| Название раздела, связывающего приложение с вебом                               | applinks (не требуется для ключей доступа)                                                                                                                      | `delegate_permission/common.handle_all_urls` (требуется для ключей доступа)                                                                                                                                                                                                                                                                                                                                                          |
| Название раздела, разрешающего совместное использование учетных данных          | webcredentials                                                                                                                                                  | `delegate_permission/common.get_login_creds`                                                                                                                                                                                                                                                                                                                                                                                         |
| Регистрация всех файлов ассоциации                                              | Включите и добавьте ассоциированный домен в среде разработки XCode (установка свойства для генерации файла прав)                                                | При использовании Credential Manager API регистрация assetlinks.json в манифесте не требуется для ключей доступа (однако она нужна для паролей). При неиспользовании Credential Manager API необходимо указать имена хостов с помощью записи `<data>` в AndroidManifest.xml в конкретном Activity (часть исходного кода Android-приложения). У тега `<intent-filter android:autoVerify="true">` должен быть атрибут autoVerify=true. |

Для [Flutter](https://www.corbado.com/blog/flutter-passkeys-package) применяется соответствующее правило Android
или iOS. Единственной специфичной для [Flutter](https://www.corbado.com/blog/flutter-passkeys-package) настройкой
является регистрация файлов ассоциации, куда вы должны добавить:

- Для Android:
  [flutter_deeplinking_enabled в AndroidManifest.xml](https://docs.flutter.dev/cookbook/navigation/set-up-app-links)
- Для iOS:
  [FlutterDeepLinkingEnabled true в Info.plist](https://docs.flutter.dev/cookbook/navigation/set-up-universal-links)

## 7. Примеры действительных и недействительных Relying Party ID и файлов ассоциации

Поскольку мы на собственном опыте убедились, что работа с Relying Party ID, различными
уровнями (под)доменов и CNAME может быть весьма сложной задачей, мы представляем четыре
различных примера и объясняем, почему и как они работают.

Обратите внимание, что строка таблицы CNAME не требуется для аутентификации по ключам
доступа и является лишь результатом нашего исследования, которое мы хотели добавить.

### 7.1 Пример 1: Проверяющей стороной является корневой домен

| **Relying Party ID**                              | corbado.com                                                                                                              |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Права (только для iOS)**                        | webcredentials:corbado.com                                                                                               |
| **Расположение файла apple-app-site-association** | [https://corbado.com/.well-known/apple-app-site-association](https://corbado.com/.well-known/apple-app-site-association) |
| **Расположение файла assetlinks.json**            | [https://corbado.com/.well-known/assetlinks.json](https://corbado.com/.well-known/assetlinks.json)                       |
| **CNAME**                                         | н/д                                                                                                                      |

В этом примере файл `apple-app-site-association` / `assetlinks.json` для Corbado.com может
быть загружен без проблем при установке / обновлении нативного приложения, поскольку файл
находится в том же месте, что и Relying Party ID.

**Ключ доступа для Relying Party ID может быть создан.**

### 7.2 Пример 2: Проверяющей стороной является поддомен, и задан CNAME

| Relying Party ID                                  | auth.corbado.com                                                                                                                         |
| ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **Права (только для iOS)**                        | webcredentials:auth.corbado.com                                                                                                          |
| **Расположение файла apple-app-site-association** | [https://pro-123.passkeys.eu/.well-known/apple-app-site-association](https://pro-123.passkeys.eu/.well-known/apple-app-site-association) |
| **Расположение файла assetlinks.json**            | [https://pro-123.passkeys.eu/.well-known/assetlinks.json](https://pro-123.passkeys.eu/.well-known/assetlinks.json)                       |
| **CNAME**                                         | auth.corbado.com =&gt; pro-123.passkeys.eu                                                                                               |

В этом примере файл `apple-app-site-association` / `assetlinks.json` для auth.corbado.com
может быть загружен без проблем при установке / обновлении нативного приложения, так как
файл находится в расположении Relying Party ID, поскольку CNAME указывает с Relying Party
ID на сохраненное расположение.

**Ключ доступа для Relying Party ID может быть создан.**

### 7.3 Пример 3: Проверяющей стороной является корневой домен, и задан CNAME

| Relying Party ID                                  | corbado.com                                                                                                                              |
| ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **Права (только для iOS)**                        | webcredentials:corbado.com; webcredentials:auth.corbado.com                                                                              |
| **Расположение файла apple-app-site-association** | [https://pro-123.passkeys.eu/.well-known/apple-app-site-association](https://pro-123.passkeys.eu/.well-known/apple-app-site-association) |
| **Расположение файла assetlinks.json**            | [https://pro-123.passkeys.eu/.well-known/assetlinks.json](https://pro-123.passkeys.eu/.well-known/assetlinks.json)                       |
| **CNAME**                                         | auth.corbado.com =&gt; pro-123.passkeys.eu                                                                                               |

В этом примере файл `apple-app-site-association` / `assetlinks.json` для auth.corbado.com
может быть загружен без проблем при установке / обновлении нативного приложения, поскольку
файл, благодаря CNAME, находится там, где `auth.corbado.com` его ожидает.

НО: Файл `apple-site-association-file` / `assetlinks.json` для corbado.com не может быть
загружен при установке / обновлении нативного приложения, поскольку файл не находится по
адресу `https://corbado.com/.well-known/apple-app-site-association` /
`https://corbado.com/.well-known/assetlinks.json`, где он ожидается, и на него не
указывает CNAME.

**Ключ доступа для Relying Party ID не может быть создан.**

### 7.4 Пример 4: Проверяющей стороной является поддомен, и задано право с подстановочным знаком

| Relying Party ID                                  | auth.corbado.com                                                                                                         |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Права (только для iOS)**                        | webcredentials:\*.corbado.com                                                                                            |
| **Расположение файла apple-app-site-association** | [https://corbado.com/.well-known/apple-app-site-association](https://corbado.com/.well-known/apple-app-site-association) |
| **Расположение файла assetlinks.json**            | [https://corbado.com/.well-known/assetlinks.json](https://corbado.com/.well-known/assetlinks.json)                       |
| **CNAME**                                         | н/д                                                                                                                      |

В этом примере файл `apple-app-site-association` для corbado.com может быть загружен без
проблем при установке / обновлении нативного приложения, поскольку файл находится там, где
ожидается, и право webcredentials (`*.corbado.com`) соответствует Relying Party ID
(`auth.corbado.com`). Обратите внимание, что этот пример не работает для Android, так как
Android не работает с такими (подстановочными) правами. В целом этот способ определения
Relying Party ID не рекомендуется.

**Ключ доступа для Relying Party ID может быть создан.**

## 8. Распространенные ошибки Relying Party ID и как их избежать

### 8.1 Изменение Relying Party ID с поддомена на корневой домен

**Ошибка:**

Вы начали разработку и определили поддомен (например, `login.acme.com`) в качестве Relying
Party ID. Первые пользователи создали ключи доступа для этого Relying Party ID. Затем вы
замечаете, что эти ключи доступа также нужны для аутентификации на другом поддомене
(например, `app.acme.com`). Поскольку источник пользователя и Relying Party ID для нового
поддомена не совпадают, пользователь не может войти с помощью ключа доступа. Изменение
Relying Party ID в настройках WebAuthn на `acme.com` сделает недействительными все
существующие ключи доступа, поскольку новый источник и Relying Party ID, сохраненные в
существующих ключах доступа, не совпадают.

**Решение:**

Дважды проверьте всё на этапе определения Relying Party ID, так как это более-менее
окончательное решение. Если вы сомневаетесь и хотите быть готовыми к будущему, то есть,
возможно, другим поддоменам в будущем понадобится ключ доступа для аутентификации, мы
рекомендуем использовать корневой домен (например, acme.com) в качестве Relying Party ID,
если он не включен в [Список публичных суффиксов](https://publicsuffix.org/learn/).

### 8.2 Разные Relying Party ID для нативного и веб-приложения

**Ошибка:**

Вы разрабатываете нативное и веб-приложение одновременно. Чтобы ускорить процесс, вы
используете два разных сервера WebAuthn (с разными Relying Party ID для нативного и
веб-приложения). Когда ваши пользователи создают первые ключи доступа, соответствующий
Relying Party ID сохраняется в ключе доступа. Разрешить вход на разных устройствах /
платформах с одним и тем же ключом доступа, например, с ключом доступа, созданным в
веб-приложении, при попытке войти в нативное приложение, больше не получится. Объединение
двух серверов WebAuthn приведет к отказу от ключей доступа, зарегистрированных на старом
сервере WebAuthn (старом Relying Party ID), и ваши пользователи не смогут входить с
помощью этих ключей доступа.

**Решение:**

Если у вас несколько приложений (например, веб-приложение и нативное приложение), всегда
используйте только один сервер WebAuthn и определяйте только один Relying Party ID для
всех ваших приложений. Связывание этих приложений можно выполнить с помощью шагов,
описанных выше.

### 8.3 Недействительные и недоступные файлы ассоциации

**Ошибка:**

Вы начинаете разработку своего приложения, настроили файлы ассоциации и развернули их на
своем сервере. По какой-то причине вы по-прежнему получаете сообщения об ошибках и не
можете найти их причину.

**Решение:**

Потенциальной причиной сообщения об ошибке может быть неправильный формат или
недоступность файла ассоциации. Перед развертыванием любого файла ассоциации на сервере мы
настоятельно рекомендуем проверить его действительность и доступность (часто эти файлы
могут находиться за [надежным VPN](https://cybernews.com/best-vpn/most-secure-vpns/) или
брандмауэром, который предотвращает надлежащий доступ для сканеров Apple и Google) с
помощью инструментов, предоставляемых для
[iOS ](https://branch.io/resources/aasa-validator/)и Android.

### 8.4 Файл apple-app-site-association еще не кэширован CDN Apple

**Ошибка:**

Вы развернули файл apple-app-site-association на своем сервере и хотите сразу же начать
создавать ключ доступа на тестовом устройстве. По какой-то причине вы не можете создать
ключ доступа и получаете сообщения об ошибках.

**Решение:**

Причина этих сообщений об ошибках заключается в том, что устройства iOS загружают файл
`apple-app-site-association` для проверки проверяющей стороны (Relying Party). При этом
устройства iOS не отправляют прямой запрос на ваш сервер, а используют CDN. И устройство,
и CDN кэшируют файл `apple-app-site-association` после его успешного извлечения. Из-за
этой функции кэширования новые изменения в вашем файле `apple-app-site-association` не
сразу отражаются в вашем приложении. Кэширование файла `apple-app-site-association` в CDN
может занять до 24 часов. Чтобы обойти это ограничение во время разработки, вы можете
добавить `?mode=developer` к Relying Party ID и полностью отключить кэширование (например,
Relying Party ID будет иметь вид `acme.com?mode=developer`).

### 8.5 Несовместимость эмулятора Android и версии API

**Ошибка:**

Вы начинаете разработку приложения для Android и хотите протестировать его на эмуляторе
Android. По какой-то причине вы получаете сообщения об ошибках, даже если правильно
настроили эмулятор Android и другие приложения, похоже, работают на нем нормально.

**Решение:**

Версии Android, поддержка Play Store и версии API играют важную роль при тестировании
приложения с ключами доступа. Кроме того, вы должны войти в учетную запись Google.
Подробности см. в разделе устранения неполадок.

## 9. Рекомендации

### 9.1 Общие рекомендации

Наша общая рекомендация — тщательно выбирать Relying Party ID с учетом ландшафта вашего
приложения и требований. Ниже мы собрали наиболее распространенные варианты использования,
но в целом мы рекомендуем вам **стараться выбирать корневой домен в качестве Relying Party
ID** и настраивать аутентификацию именно так. В Corbado мы также предварительно настроили
это для вас (поскольку это часть нашего подхода к обеспечению бесшовной аутентификации по
ключам доступа для всех технических конфигураций. Наши компоненты пользовательского
интерфейса и SDK готовы к использованию с вашим корневым доменом в качестве Relying Party
ID).

| Случай                                                                                                                                                                                                                                                                                                                                                                                                                                | Рекомендация                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **A) У вас есть один корневой домен:**<br/><br/>Пример: acme.com<br/><br/>Все приложения и аутентификация работают на этом корневом домене или его поддоменах                                                                                                                                                                                                                                                                         | ✔️ Выберите корневой домен в качестве Relying Party ID, так как это не вызовет проблем для веб- или нативных приложений.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| **B) У вас несколько корневых доменов:**<br/><br/>Пример: kayak.com, kayak.co.uk, kayak.de<br/><br/>Вы обслуживаете своих пользователей с разных международных доменов верхнего уровня. Kayak.com для США и kayak.co.uk для Великобритании, или у вас совершенно разные корневые домены, которые должны позволять одним и тем же пользователям входить с теми же ключами доступа.                                                     | ⚠️ В ваших веб-приложениях для обмена ключами доступа требуется настройка запросов связанных источников (Related Origin Requests) через `.well-known/webauthn`, чтобы разрешить указанным источникам использовать общий RP ID (поддержка браузерами различается; проверьте совместимость). В качестве альтернативы выберите общий корневой домен аутентификации.<br/><br/>✔️ Вы можете подключить свои нативные приложения к любому количеству корневых доменов, если у вас есть контроль над корневыми файлами ассоциации.<br/><br/>❌ В случае, если вы позже захотите перейти на другой корневой домен для хостинга вашего веб-сайта, вы не сможете использовать уже созданные ключи доступа, поскольку вам придется провести ребрендинг и изменить домен (Relying Party ID). |
| **C) У вас еще НЕТ корневого домена, вы работаете только на бэкенде или на публичном поддомене. Есть некоторые случаи, когда это может произойти:**<br/><br/>1. Вы работаете на свободно доступном поддомене, где корневой домен не находится под вашим контролем (корневой домен указан на сайте [https://publicsuffix.org/](https://publicsuffix.org/)), например URL-адреса CDN<br/><br/>2. Вы работаете над нативным приложением. | ❌ На публичных поддоменах вы не можете управлять файлами ассоциации на корневом уровне корневого домена. Следовательно, ключи доступа не будут работать нативно.<br/><br/>⚠️ Единственный способ исправить это для некоторых сервисов — перейти на платный тариф, где вы сможете определить CNAME или получить для себя собственный корневой домен.                                                                                                                                                                                                                                                                                                                                                                                                                             |

### 9.2 Рекомендации при использовании Corbado

Ниже мы приводим очень конкретное дерево решений, которое должно помочь вам определить
правильный Relying Party ID и то, как следует обрабатывать / размещать файлы ассоциации
при использовании Corbado в качестве решения для ключей доступа.

Первое решение — находитесь ли вы в среде разработки или в производственной среде.
Следующий уровень решений, которые вам необходимо принять, зависит от ландшафта вашего
приложения: у вас есть только нативное приложение или нативное и веб-приложение.

#### A) Разработка (Development)

Для среды разработки мы предполагаем, что вы хотите быстро начать разработку и
тестирование. Relying Party ID можно будет изменить позже, если вы захотите запустить
продукт (go live).

##### A1) Только нативное приложение (Native-Only)

- Установите Relying Party ID = `pro-XXX.frontendapi.cloud.corbado.io` (значение по
  умолчанию)
- Corbado размещает файл ассоциации за вас
- Никаких действий с DNS с вашей стороны

##### A2) Нативное и веб-приложение

Непросто одновременно тестировать и веб-приложение, и нативное приложение

**Вариант 1:**

Либо вы устанавливаете Relying Party ID = `pro-XXX.frontendapi.cloud.corbado.io` (работает
нативное приложение), ИЛИ устанавливаете Relying Party ID = `localhost` (работает
веб-приложение)

**Вариант 2:**

Единственное решение, позволяющее одновременно работать нативному и веб-приложению, —
использовать локальный обратный прокси-сервер (reverse proxy) (это довольно костыльное
решение):

- Установите Relying Party ID = `acme-dev.com`
- Установите CNAME с `acme-dev.com` =&gt; `pro-XXX.frontendapi.cloud.corbado.io`
- Добавьте локальную запись в `/etc/hosts`: `localhost acme-dev.com`
- Добавьте обратный прокси-сервер (nginx) с правилом для `acme-dev.com` =&gt;
  `localhost:3000` (в качестве примера)

#### B) Продакшен (Production)

В производственной среде вам нужно решить, устраивает ли вас поддомен в качестве Relying
Party ID (например, `auth.acme.com`) или вы хотите использовать корневой домен в качестве
Relying Party ID (например, `acme.com`).

##### B1) Поддомен в качестве Relying Party ID

###### B1.1) Только нативное приложение

- Установите Relying Party ID = `auth.acme.com`
- Corbado размещает файл ассоциации за вас
- Установите CNAME с `auth.acme.com` =&gt; `pro-XXX.frontendapi.cloud.corbado.io`

###### B1.2) Нативное и веб-приложение

- Установите Relying Party ID = `auth.acme.com`
- Corbado размещает файл ассоциации за вас
- Установите CNAME с `auth.acme.com` =&gt; `pro-XXX.frontendapi.cloud.corbado.io` (также
  требуется для работы файлов cookie, если вы используете управление сеансами Corbado)

##### B2) Корневой домен в качестве Relying Party ID

###### B2.1) Только нативное приложение

- Установите Relying Party ID = `acme.com`
- Разместите файл ассоциации самостоятельно на своем собственном сервере по адресу
  `acme.com/.well-known/<association file>`
- Никаких действий с DNS с вашей стороны

###### B2.2) Нативное и веб-приложение

- Установите Relying Party ID = `acme.com`
- Разместите файл ассоциации самостоятельно на своем собственном сервере по адресу
  `acme.com/.well-known/<association file>`
- Если вы используете управление сеансами Corbado, вам нужно установить CNAME с
  `auth.acme.com` =&gt; `pro-XXX.frontendapi.cloud.corbado.io`, чтобы файлы cookie
  работали (этот CNAME не нужен для Relying Party ID, исключительно для управления
  сеансами)

Следующее дерево решений резюмирует все пути конфигурации.

## 10. Заключение

Идентификатор проверяющей стороны (Relying Party ID) является краеугольным камнем WebAuthn
и аутентификации на основе ключей доступа, обеспечивающим надежную защиту от фишинга.
Крайне важно правильно его настроить, понять тонкости сопоставления доменов и обеспечить
корректное развертывание для нативных приложений. В этой статье мы рассказали, как
настроить их правильно и как справляться с различными ошибками. Как только конфигурация
вашего rpID станет надежной, сосредоточьтесь на оптимизации потоков создания ключей
доступа и потоков входа по ключам доступа для стимулирования реального внедрения. Для
получения дополнительной информации о настройке ключей доступа для нативных приложений мы
рекомендуем прочитать о ключах доступа во [Flutter](https://www.corbado.com/blog/flutter-passkeys-package).

Если у вас есть дополнительные вопросы или вам нужна помощь, не стесняйтесь
[обращаться к нам](https://bit.ly/passkeys-community).

## Часто задаваемые вопросы

### Как идентификатор проверяющей стороны предотвращает фишинг при аутентификации с помощью ключей доступа?

Аутентификатор сравнивает фактический источник (origin) браузера с идентификатором
проверяющей стороны (Relying Party ID), хранящимся в ключе доступа. Если злоумышленник
размещает поддельный сайт на другом домене, несовпадение источников автоматически приводит
к сбою аутентификации, даже если в поддельном запросе указан легитимный RP ID. Эта
привязка означает, что ключ доступа, зарегистрированный на paypal.com, не может быть
использован на похожем домене, таком как paybal.com.

### Что произойдет, если я изменю свой идентификатор проверяющей стороны WebAuthn после того, как пользователи уже зарегистрировали ключи доступа?

Изменение RP ID делает недействительными все существующие ключи доступа, поскольку
сохраненный RP ID в каждой учетной записи больше не будет совпадать с новым значением.
Единственным исключением является случай, когда новый RP ID является поддоменом старого
или когда настроены запросы связанных источников (Related Origin Requests) через
`.well-known/webauthn`. Чтобы избежать этой необратимой проблемы, с самого начала
выбирайте корневой домен в качестве RP ID.

### Почему мой ключ доступа для iOS не работает сразу после развертывания файла apple-app-site-association?

iOS не загружает файл apple-app-site-association напрямую с вашего сервера. Она использует
CDN Apple, кэширование недавно развернутого или обновленного файла в которой может занять
до 24 часов. Во время разработки добавьте `?mode=developer` к идентификатору проверяющей
стороны, чтобы полностью обойти кэширование.

### Должен ли я использовать поддомен или корневой домен в качестве идентификатора проверяющей стороны для ключей доступа?

Рекомендуется использовать корневой домен (например, acme.com), поскольку ключи доступа,
созданные на любом поддомене, могут проходить аутентификацию на всех поддоменах этого
корня. RP ID в виде поддомена ограничивает использование ключа доступа этим поддоменом и
его дочерними элементами, что в дальнейшем может нарушить потоки между поддоменами. Если у
вас несколько корневых доменов, таких как acme.com и acme.co.uk, настройте запросы
связанных источников (Related Origin Requests) через `.well-known/webauthn`, чтобы
разрешить повторное использование ключей доступа между ними.
