Проблема, которую решают запросы связанного происхождения
Ключи доступа привязаны к конкретному веб-сайту и могут использоваться только для входа на тот веб-сайт, для которого они были созданы.
Это указано в идентификаторе проверяющей стороны (RP ID), который для ключей доступа, созданных для домена example.com, может быть www.example.com
или example.com
.
Хотя идентификаторы RP не позволяют использовать ключи доступа в качестве единых учетных данных для повсеместной аутентификации, они создают проблемы для:
- Сайты с несколькими доменами . Пользователи не могут использовать один и тот же ключ доступа для входа в разные домены разных стран (например,
example.com
иexample.co.uk
), которыми управляет одна и та же компания. - Фирменные домены . Пользователи не могут использовать одни и те же учетные данные в разных доменах, используемых одним брендом (например,
acme.com
иacmerewards.com
). - Мобильные приложения . Мобильные приложения часто не имеют собственного домена, что усложняет управление учетными данными.
Существуют обходные пути, основанные на федерации удостоверений, и другие, основанные на iframe, но в некоторых случаях они неудобны. Связанные запросы происхождения предлагают решение.
Решение
С помощью запросов на связанное происхождение веб-сайт может указать источники, которым разрешено использовать его идентификатор RP.
Это открывает пользователям возможность повторно использовать один и тот же ключ доступа на нескольких сайтах, которыми вы управляете.
Чтобы использовать запросы связанного происхождения, вам необходимо предоставить специальный файл JSON по определенному URL-адресу https://{RP ID}/.well-known/webauthn
. Если example.com
хочет разрешить дополнительным источникам использовать его в качестве идентификатора RP, он должен предоставить следующий файл по адресу https://example.com/.well-known/webauthn:
{
"origins": [
"https://example.co.uk",
"https://example.de",
"https://example-rewards.com"
]
}
В следующий раз, когда любой из этих сайтов вызовет создание ключа доступа ( navigator.credentials.create
) или аутентификацию ( navigator.credentials.get
), который использует example.com
в качестве идентификатора RP, браузер заметит идентификатор RP, который не соответствует запрашивающему источнику. . Если браузер поддерживает запросы связанного происхождения, он сначала ищет файл webauthn
по адресу https://{RP ID}/.well-known/webauthn
. Если файл существует, браузер проверяет, внесен ли источник, отправляющий запрос, в список разрешенных в этом файле. Если это так, он переходит к шагам создания пароля или аутентификации. Если браузер не поддерживает запросы связанного происхождения, он выдает SecurityError
.
Поддержка браузера
- Chrome: поддерживается начиная с Chrome 128 .
- Safari: поддерживается начиная с macOS 15 beta 3 и на мобильных устройствах iOS 18 beta 3.
- Firefox: Ожидание позиции .
Как настроить связанные запросы происхождения
В следующей демонстрации используется пример двух сайтов: https://ror-1.glitch.me
и https://ror-2.glitch.me
.
Чтобы пользователи могли входить в систему с одним и тем же паролем на обоих этих сайтах, он использует запросы связанного происхождения, чтобы позволить ror-2.glitch.me
использовать ror-1.glitch.me
в качестве своего идентификатора RP.
Демо
https://ror-2.glitch.me реализует запросы связанного происхождения для использования ror-1.glitch.me в качестве идентификатора RP, поэтому и ror-1
, и ror-2
используют ror-1.glitch.me
в качестве идентификатора RP. после создания пароля или аутентификации с его помощью.
Мы также внедрили общую базу данных паролей на этих сайтах.
Обратите внимание на следующий пользовательский опыт:
- Вы можете успешно создать ключ доступа и пройти аутентификацию с его помощью на
ror-2
, даже если его идентификатор RP равенror-1
(а неror-2
). - После того как вы создадите ключ доступа на
ror-1
илиror-2
, вы сможете аутентифицироваться с его помощью как наror-1
, так и наror-2
. Посколькуror-2
в качестве идентификатора RP указанror-1
, выполнение запроса на создание пароля или аутентификацию с любого из этих сайтов аналогично выполнению запроса на ror-1. Идентификатор RP — единственное, что связывает запрос с источником. - После того как вы создадите ключ доступа на
ror-1
илиror-2
, Chrome сможет автоматически заполнить его как наror-1
, так и наror-2
. - Учетные данные, созданные на любом из этих сайтов, будут иметь идентификатор RP
ror-1
.
См. код:
- См. файл
./well-known/webauthn
, настроенный в кодовой базе ror-1 . - См. вхождения
RP_ID_ROR
в кодовой базе ror-2 .
Шаг 1. Внедрите общую базу данных учетных записей
Если вы хотите, чтобы ваши пользователи могли входить в систему с одним и тем же ключом доступа на site-1
и site-2
, внедрите базу данных учетных записей, которая будет использоваться на этих двух сайтах.
Шаг 2. Настройте JSON-файл .well-known/webauthn на сайте-1.
Сначала настройте site-1.com
так, чтобы site-2.com
мог использовать его в качестве идентификатора RP. Для этого создайте JSON-файл webauthn:
{
"origins": [
"https://site-2.com"
]
}
Объект JSON должен содержать ключ с именем origins, значение которого представляет собой массив из одной или нескольких строк, содержащих веб-источники.
Важное ограничение: максимум 5 ярлыков.
Каждый элемент этого списка будет обработан для извлечения метки eTLD+1. Например, метки eTLD + 1 для example.co.uk
и example.de
являются example
. Но метка eTLD + 1 сайта example-rewards.com
— example-rewards
. В Chrome максимальное количество ярлыков — 5.
Шаг 3. Разместите свой JSON .well-known/webauthn на сайте-1.
Затем разместите свой файл JSON по адресу site-1.com/.well-known/webauthn
.
Например, в экспрессе:
app.get("/.well-known/webauthn", (req, res) => {
const origins = {
origins: ["https://site-2.com"],
};
return res.json(origins);
});
Здесь мы используем express res.json
, который уже устанавливает правильный content-type
( 'application/json'
);
Шаг 4. Укажите желаемый идентификатор RP на сайте-2.
В вашей кодовой базе site-2
установите site-1.com
в качестве идентификатора RP везде, где это необходимо:
- При создании учетных данных:
- Установите
site-1.com
в качестве идентификатора RP вoptions
создания учетных данных, которые передаются во внешний вызовnavigator.credentials.create
и обычно генерируются на стороне сервера. - Установите
site-1.com
в качестве ожидаемого идентификатора RP при выполнении проверки учетных данных перед сохранением его в базе данных.
- Установите
- При аутентификации:
- Установите
site-1.com
в качестве идентификатора RP вoptions
аутентификации, которые передаются во внешний вызовnavigator.credentials.get
и обычно генерируются на стороне сервера. - Установите
site-1.com
в качестве ожидаемого идентификатора RP, который будет проверяться на сервере, при выполнении проверки учетных данных перед аутентификацией пользователя.
- Установите
Поиск неисправностей
Другие соображения
Делитесь ключами доступа между сайтами и мобильными приложениями
Связанные запросы происхождения позволяют вашим пользователям повторно использовать ключ доступа на нескольких сайтах . Чтобы разрешить пользователям повторно использовать ключ доступа на веб-сайте и в мобильном приложении , используйте следующие методы:
- В Chrome: ссылки на цифровые ресурсы . Дополнительную информацию см. в разделе «Добавление поддержки для ссылок на цифровые активы» .
- В Safari: Связанные домены .
Делитесь паролями между сайтами
Связанные запросы происхождения позволяют вашим пользователям повторно использовать ключ доступа на разных сайтах. Решения для обмена паролями между сайтами различаются в зависимости от менеджера паролей. Для Менеджера паролей Google используйте ссылки на цифровые активы . В Safari другая система .
Роль менеджеров учетных данных и пользовательских агентов
Это выходит за рамки вашей компетенции как разработчика сайта, но учтите, что в долгосрочной перспективе идентификатор RP не должен быть видимым для пользователя понятием в пользовательском агенте или диспетчере учетных данных, который используют ваши пользователи. Вместо этого пользовательские агенты и менеджеры учетных данных должны показывать пользователям , где использовались их учетные данные. Для реализации этого изменения потребуется время. Временным решением было бы отображать как текущий веб-сайт, так и исходный сайт регистрации.