Вход в систему с использованием федерации сторон
В этой статье описывается процесс, с помощью которого сторона, полагающаяся на API (RP), может использовать API управления федеративными учетными данными (FedCM) для выполнения входа в систему с использованием поставщика удостоверений (IdP).
Вызов метода get()
Стороны, полагающиеся на API (RP), могут вызвать navigator.credentials.get() с параметром identity, чтобы запросить вход пользователя в RP с использованием существующей учетной записи IdP, в которой пользователь уже авторизован в браузере. IdP идентифицирует RP по его clientId, который был выдан IdP RP в отдельном процессе, специфичном для данного IdP. IdP идентифицирует конкретного пользователя, используя предоставленные браузеру учетные данные (куки) при входе.
Метод возвращает промис, который выполняется с объектом IdentityCredential, если идентификация пользователя успешно прошла валидацию IdP. Этот объект содержит токен, который включает информацию об идентификации пользователя, подписанную с использованием цифрового сертификата IdP. цифрового сертификата.
RP отправляет токен на свой сервер для проверки сертификата. При успешной проверке RP может использовать (теперь надёжную) информацию об идентификации из токена для входа пользователя в свою услугу (начало новой сессии), регистрации нового пользователя и т.д.
Если пользователь никогда не был авторизован в IdP или вышел из системы, метод get() отклоняется с ошибкой, и RP может перенаправить пользователя на страницу входа IdP для входа или создания учетной записи.
Примечание: Точный формат и содержание токена валидации скрыты для API FedCM и браузера. IdP определяет синтаксис и использование токена, а RP должен следовать инструкциям, предоставленным IdP (например, см. Проверка токена Google ID на стороне сервера), чтобы убедиться в его правильном использовании.
Типичный запрос может выглядеть следующим образом:
async function signIn() {
const identityCredential = await navigator.credentials.get({
identity: {
context: "signup",
providers: [
{
configURL: "https://accounts.idp.example/config.json",
clientId: "********",
nonce: "******",
loginHint: "user1@example.com",
},
],
},
});
}
Свойство identity.providers принимает массив, содержащий один объект, который указывает путь к файлу конфигурации IdP (configURL) и идентификатор клиента RP (clientId), выданный IdP.
Примечание: В настоящее время FedCM позволяет вызывать API только с одним IdP, т.е. массив identity.providers должен иметь длину 1. Для предоставления пользователю возможности выбора поставщика удостоверений RP должен вызывать get() отдельно для каждого. Это может измениться в будущем.
В приведённом выше примере также включены несколько дополнительных функций:
-
identity.contextуказывает контекст, в котором пользователь проходит аутентификацию с FedCM. Например, является ли это первой регистрацией для этой учетной записи или входом в существующую учетную запись? Браузер использует эту информацию для изменения текста в своём пользовательском интерфейсе FedCM, чтобы лучше соответствовать контексту. - Свойство
nonceпредоставляет случайное значение nonce, гарантирующее, что ответ выдан для этого конкретного запроса, предотвращая атаки повторного использования. - Свойство
loginHintдаёт подсказку о варианте(ах) учетной записи, которые браузер должен отобразить для входа пользователя. Эта подсказка сопоставляется со значениямиlogin_hints, которые IdP предоставляет с помощью конечной точки списка учетных записей.
Браузер запрашивает файл конфигурации IdP и выполняет поток входа в систему, подробно описанный ниже. Дополнительную информацию о взаимодействии, которое может ожидать пользователь от пользовательского интерфейса, предоставленного браузером, см. в статье об авторизации на стороне полагающейся стороны с помощью поставщика удостоверений.
Поток входа в систему FedCM
В потоке входа в систему участвуют три стороны — приложение RP, сам браузер и IdP. На следующей диаграмме показано, что происходит визуально.
Поток выглядит следующим образом:
-
Приложение RP вызывает
navigator.credentials.get()для запуска потока входа в систему. -
Из
configURL, предоставленного в вызовеget(), браузер запрашивает два файла:- Файл известного ресурса (
/.well-known/web-identity), доступный по адресу/.well-known/web-identityв eTLD+1configURL. - Файл конфигурации IdP (
/config.json), доступный по адресуconfigURL.
Оба запроса являются
GETзапросами, которые не используют куки и не следуют перенаправлениям. Это эффективно предотвращает IdP от получения информации о том, кто сделал запрос и какая RP пытается подключиться.Все запросы, отправляемые браузером через FedCM, включают заголовок
для предотвращения CSRF-атак. Все конечные точки IdP должны подтверждать включение этого заголовка.Sec-Fetch-Dest: webidentity - Файл известного ресурса (
-
IdP отвечает файлом известного ресурса и файлами
config.json. Браузер проверяет URL файла конфигурации в запросеget()по списку допустимых URL конфигураций внутри файла известного ресурса. -
Если у браузера установлен статус входа в систему IdP
"logged-in", он делает запрошенный запрос (с куки, идентифицирующими вошедшего пользователя) кaccounts_endpointв файле конфигурации IdP для получения данных о учетной записи пользователя. Это запросGETс куки, но без параметраclient_idили заголовкаOrigin. Это эффективно предотвращает IdP от получения информации о том, в какую RP пользователь пытается войти. В результате возвращаемый список учетных записей является независимым от RP.Примечание: Если статус входа в систему IdP равен
"logged-out", вызовget()отклоняется с ошибкойNetworkErrorDOMExceptionи не отправляет запрос кaccounts_endpointIdP. В этом случае разработчик должен обрабатывать поток, например, попросив пользователя войти в соответствующий IdP. Обратите внимание, что отказ может произойти с некоторой задержкой, чтобы избежать утечки статуса входа в систему IdP в RP. -
IdP отвечает информацией об учетной записи, запрошенной из
accounts_endpoint. Это массив всех учетных записей, связанных с куки IdP пользователя для всех RP, связанных с IdP. -
Необязательно Если в файле конфигурации IdP указано, браузер отправляет незащищённый запрос к
client_metadata_endpointдля получения местоположения страниц пользовательского соглашения и политики конфиденциальности RP. Это запросGET, отправленный с параметромclientIdв вызовget(), без использования куки. -
Необязательно IdP отвечает URL, запрошенными из
client_metadata_endpoint. -
Браузер использует полученную информацию для создания пользовательского интерфейса, позволяющего выбрать учетную запись для входа в RP (если доступно более одной). Также пользовательский интерфейс запрашивает разрешение на вход в RP с использованием выбранной федеративной учетной записи IdP.
Примечание: На этом этапе, если пользователь ранее авторизовался в RP с использованием федеративной учетной записи в текущей сессии браузера (т. е. создал новую учетную запись или вошёл на сайт RP с использованием существующей учетной записи), он может быть в состоянии автоматически повторно войти, в зависимости от значения опции
mediationв вызовеget(). В таком случае пользователь войдёт автоматически без ввода своих учетных данных, как толькоget()будет вызван. Более подробную информацию см. в разделе Автоматическое повторное подключение. -
Если пользователь предоставляет разрешение, браузер делает запрошенный запрос с учетными данными на
id_assertion_endpointдля получения токена валидации от IdP для выбранной учетной записи.Учетные данные отправляются в запросе HTTP
POSTс куки и типом содержимогоapplication/x-www-form-urlencoded.Если вызов не удался, в ответ возвращается полезная нагрузка с ошибкой, как описано в ответах IdP об ошибках подтверждения, и промис, возвращаемый
get(), отклонится с ошибкой. -
IdP проверяет, соответствует ли идентификатор учетной записи, отправленный RP, идентификатору учетной записи, в которой пользователь уже авторизован, и что
Originсоответствует источнику RP, который будет зарегистрирован предварительно в IdP. При успешной проверке он отправляет запрашиваемый токен валидации.Примечание: Происхождение RP будет зарегистрировано в IdP в отдельном процессе при первом подключении RP к IdP. Этот процесс будет специфичным для каждого IdP.
-
После завершения потока промис
get()выполняется с объектомIdentityCredential, который предоставляет дополнительные возможности RP. В частности, этот объект содержит токен, который RP может проверить, полученный от IdP (используя сертификат), и который содержит надёжную информацию о вошедшем пользователе. После проверки токена RP может использовать содержащуюся в нём информацию для входа пользователя и запуска новой сессии, регистрации пользователя и т.д. Формат и структура токена зависят от IdP и не связаны с API FedCM (RP должен следовать инструкциям IdP).
Автоматическое повторное подключение
Автоматическая повторная аутентификация FedCM позволяет пользователям автоматически повторно аутентифицироваться, когда они пытаются снова войти в RP после первоначальной аутентификации с помощью FedCM. «Первоначальная аутентификация» — это момент, когда пользователь создает учетную запись или входит в веб-сайт RP через диалоговое окно входа FedCM в первый раз на сайте RP в этом же экземпляре браузера.
После первоначальной аутентификации автоматическая повторная аутентификация может быть использована для повторного входа на веб-сайт RP автоматически, без необходимости отображения пользователю запроса подтверждения «Продолжить как…». Если пользователь недавно разрешил федеративную входную процедуру для конкретной учетной записи, нет никакой пользы для конфиденциальности или безопасности для немедленного принуждения к повторному подтверждению со стороны пользователя.
Поведение автоматической повторной аутентификации контролируется опцией mediation в вызове get():
async function signIn() {
const identityCredential = await navigator.credentials.get({
identity: {
providers: [
{
configURL: "https://accounts.idp.example/config.json",
clientId: "********",
},
],
},
mediation: "optional", // this is the default
});
// isAutoSelected is true if auto-reauthentication occurred.
const isAutoSelected = identityCredential.isAutoSelected;
}
Автоматическая повторная аутентификация может произойти, если mediation установлено в optional или silent.
С этими mediation опциями, автоматическая повторная аутентификация произойдёт при следующих условиях:
- FedCM доступен для использования. Например, пользователь не отключил FedCM ни глобально, ни в настройках RP.
- Пользователь использовал только одну учетную запись для входа на веб-сайт RP в этом браузере через FedCM.
- Пользователь вошёл в IdP с этой учетной записью.
- Автоматическая повторная аутентификация не происходила в течение последних 10 минут. Это ограничение введено, чтобы предотвратить автоматическую повторную аутентификацию сразу после выхода пользователя — что сделало бы пользовательский опыт довольно непонятным.
- RP не вызывал
preventSilentAccess()после предыдущего входа. Это может использоваться RP для явного отключения автоматической повторной аутентификации, если необходимо.
Когда эти условия выполнены, попытка автоматической повторной аутентификации пользователя начинается сразу после вызова get(). Если автоматическая повторная аутентификация успешна, пользователь войдёт на сайт RP снова без отображения запроса подтверждения, используя ту же учетную запись IdP и валидированный токен, что и раньше.
Если автоматическая повторная аутентификация не удалась, поведение зависит от значения mediation:
-
optional: пользователю будет отображено диалоговое окно и будет запрошено повторное подтверждение. В результате, этот параметр имеет смысл использовать на странице, где пользовательский путь не находится в процессе, например, на странице входа RP. -
silent: Обещаниеget()отклонится, и разработчик должен будет направить пользователя обратно на страницу входа, чтобы начать процесс заново. Этот вариант подходит для страниц, где пользовательский путь находится в процессе и требуется сохранить его авторизованным до завершения, например, на страницах процесса оформления заказа на веб-сайте электронной коммерции.
Примечание: Свойство IdentityCredential.isAutoSelected указывает, была ли федеративная входная процедура выполнена с использованием автоматической повторной аутентификации. Это полезно для оценки производительности API и соответствующего улучшения пользовательского интерфейса. Кроме того, если оно недоступно, пользователю может быть предложено войти с явным пользовательским подтверждением, что является вызовом get() с mediation: required.
См. также
- API федерального управления учетными данными на developers.google.com (2023)
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/FedCM_API/RP_sign-in