Разрешите повторное использование пароля на ваших сайтах с помощью запросов связанного происхождения.

Мод Налпас
Maud Nalpas

Ключи доступа привязаны к конкретному веб-сайту и могут использоваться только для входа на тот веб-сайт, для которого они были созданы.

Это указано в идентификаторе проверяющей стороны (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 .
Chrome выполняет автозаполнение на обоих сайтах.
Благодаря запросам связанного происхождения пользователи могут использовать одни и те же учетные данные ключа доступа для ror-1 и ror-2. Chrome также автоматически заполнит учетные данные.

См. код:

Шаг 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.comexample-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.
Сообщение об ошибке в Chrome при создании учетных данных. Эта ошибка выдается, если ваш файл `.well-known/webauthn` не найден по адресу `https://{RP ID}/.well-known/webauthn`.
Всплывающее сообщение об ошибке в Chrome.
Сообщение об ошибке в Chrome при создании учетных данных. Эта ошибка выдается, если ваш файл `.well-known/webauthn` найден, но в нем не указан источник, из которого вы пытаетесь создать учетные данные.

Другие соображения

Делитесь ключами доступа между сайтами и мобильными приложениями

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

Делитесь паролями между сайтами

Связанные запросы происхождения позволяют вашим пользователям повторно использовать ключ доступа на разных сайтах. Решения для обмена паролями между сайтами различаются в зависимости от менеджера паролей. Для Менеджера паролей Google используйте ссылки на цифровые активы . В Safari другая система .

Роль менеджеров учетных данных и пользовательских агентов

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