Внедрение решения для идентификации с помощью FedCM на стороне проверяющей стороны.

Для включения FedCM на своем сайте зависимым сторонам необходимо выполнить следующие шаги:

Вызовите API FedCM на стороне, полагающейся на данные.

После того как конфигурация и конечные точки поставщика идентификации (IdP) станут доступны, поставщики идентификации (RP) могут вызвать navigator.credentials.get() для запроса разрешения пользователю на вход в систему RP с помощью IdP.

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

  if ('IdentityCredential' in window) {
    // If the feature is available, take action
  } else {
    // FedCM is not supported, use a different identity solution
  }

Чтобы разрешить пользователю войти в систему поставщика идентификации (IdP) на стороне поставщика услуг (RP) с помощью FedCM, RP может вызвать метод navigator.credentials.get() . Начиная с Chrome 136, RP может поддерживать несколько поставщиков идентификации, указывая массив нескольких поставщиков идентификации в одном вызове navigator.credentials.get() , например:

  const credential = await navigator.credentials.get({
      identity: {
        // Specify the IdP (or multiple IdPs, supported from Chrome 136) this Relying Party supports
        providers: [
        {
              configURL: 'https://accounts.idp-1.example/config.json',
              clientId: '********'
        },
        {
          configURL: 'https://accounts.idp-2.example/config.json',
          clientId: '********'
        }]
      }
    },
  );
  const { token } = credential;

  // Get the current IdP's configURL to identify which provider the user is signed in with
  const currentIdpConfigUrl = credential.configURL;
  if (currentIdpConfigUrl === 'https://idp1.example/foo.json') {
    // handle the case where the user signed in with idp1
  } else if (currentIdpConfigUrl === 'https://idp2.example/bar.json') {
    // handle the case where the user signed in with idp2
    }

Оцените функцию работы с несколькими поставщиками идентификации (IdP) , войдя в систему с помощью IdP1 и IdP2 .

Свойство контекста

С помощью необязательного свойства context , RP может изменять строку в диалоговом окне пользовательского интерфейса FedCM (например, "Войти в rp.example…", "Использовать idp.example…") для учета предопределенных контекстов аутентификации. Свойство context может принимать следующие значения:

  • signin (по умолчанию)
  • signup
  • use
Диаграмма, поясняющая компоненты пользовательского интерфейса диалогового окна FedCM: в верхнем левом углу отображается значок. Справа от значка находится контекстный компонент, отображающий сообщение «Войти в RP с помощью IdP». Внизу находится кнопка «Продолжить» с настраиваемым текстом и цветом фона.
Как брендинг применяется к диалогу FedCM

Например, установка context для use приведет к следующему сообщению:

Диалоговое окно FedCM, отображающее настраиваемое контекстное сообщение: вместо «Войти с помощью FedCM» контекстное сообщение гласит «Использовать FedCM».
Диалоговое окно FedCM, отображающее настраиваемое контекстное сообщение.

Браузер обрабатывает сценарии регистрации и входа в систему по-разному в зависимости от наличия поля approved_clients в ответе от конечной точки списка учетных записей . Браузер не будет отображать текст-предупреждение «Чтобы продолжить...», если пользователь уже зарегистрировался в RP.

Свойство providers принимает массив объектов IdentityProvider , обладающих следующими свойствами:

Поставщики недвижимости

Свойство providers принимает массив объектов IdentityProvider , обладающих следующими свойствами:

Свойство Описание
configURL (обязательно) Полный путь к файлу конфигурации поставщика идентификации (IdP).
clientId (обязательно) Идентификатор клиента RP, выданный IdP.
loginHint (необязательно) Указав одно из значений login_hints предоставляемых конечными точками учетных записей , диалоговое окно FedCM выборочно отображает указанную учетную запись.
domainHint (необязательно) Указав одно из значений domain_hints предоставляемых конечными точками учетных записей , диалоговое окно FedCM выборочно отображает указанную учетную запись.
mode (опционально) Строка, определяющая режим пользовательского интерфейса FedCM. Она может принимать одно из следующих значений:
  • "active" : Запрос FedCM должен быть инициирован взаимодействием пользователя (например, нажатием кнопки).
  • "passive" : запрос FedCM будет инициирован без прямого взаимодействия с пользователем.
Подробнее о различиях между активным и пассивным режимами можно узнать на странице обзора .

Примечание: параметр mode поддерживается начиная с Chrome 132.
fields (необязательно) Массив строк, определяющий информацию о пользователе, которую RP должен передать IdP. Следующие поля могут быть указаны необязательно:
  • "name"
  • "username"
  • "email"
  • "tel"
  • "picture"
Примечание: API Fields поддерживается Chrome 132 и более поздними версиями. Поля "username" и "tel" поддерживаются начиная с Chrome 141.
params (необязательно) Пользовательский объект, позволяющий указывать дополнительные параметры типа «ключ-значение»:
  • scope : Строковое значение, содержащее дополнительные разрешения, которые RP необходимо запросить, например, "drive.readonly calendar.readonly"
  • nonce : Случайная строка, гарантирующая отправку ответа именно для этого запроса. Предотвращает атаки повторного воспроизведения.
  • Другие пользовательские параметры типа «ключ-значение».

Примечание: поддержка params реализована начиная с Chrome версии 132.

Активный режим

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

Для использования FedCM в активном режиме:

  1. Проверьте доступность функции в браузере пользователя.
  2. Вызов API осуществляется с помощью кратковременного действия пользователя, например, нажатия кнопки.
  3. Передайте параметр mode в вызов API:
  let supportsFedCmMode = false;
  try {
    navigator.credentials.get({
      identity: Object.defineProperty(
        // Check if this Chrome version supports the Mode API.
        {}, 'mode', {
          get: function () { supportsFedCmMode = true; }
        }
      )
    });
  } catch(e) {}

  if (supportsFedCmMode) {
    // The button mode is supported. Call the API with mode property:
    return await navigator.credentials.get({
      identity: {
        providers: [{
          configURL: 'https://idp.example/config.json',
          clientId: '123',
        }],
        // The 'mode' value defines the UX mode of FedCM.
        // - 'active': Must be initiated by user interaction (e.g., clicking a button).
        // - 'passive': Can be initiated without direct user interaction.
        mode: 'active'
      }
    });
  }

Попробуйте активный режим с помощью этой демоверсии .

Пользовательская иконка в активном режиме

Активный режим позволяет поставщикам идентификации (IdP) включать официальный логотип поставщика услуг (RP) непосредственно в ответ конечной точки метаданных клиента . Поставщик услуг должен заранее предоставить данные о своем брендинге.

Вызовите FedCM из iframe, находящегося в другом источнике.

FedCM можно вызвать из iframe, расположенного в другом источнике, используя политику разрешений identity-credentials-get , если родительский фрейм это разрешает. Для этого добавьте атрибут allow="identity-credentials-get" к тегу iframe следующим образом:

  <iframe src="https://fedcm-cross-origin-iframe.glitch.me" allow="identity-credentials-get"></iframe>

Вы можете увидеть это в действии на примере .

При желании, если родительский фрейм хочет ограничить доступ источников к FedCM, следует отправить заголовок Permissions-Policy со списком разрешенных источников.

  Permissions-Policy: identity-credentials-get=(self "https://fedcm-cross-origin-iframe.glitch.me")

Подробнее о том, как работает политика разрешений, можно узнать в статье «Управление функциями браузера с помощью политики разрешений» .

API подсказок для входа

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

Пользователи могут выборочно отображать определенную учетную запись, вызывая метод navigator.credentials.get() со свойством loginHint , содержащим одно из значений login_hints , полученных из конечной точки списка учетных записей , как показано в следующем примере кода:

  return await navigator.credentials.get({
    identity: {
      providers: [{
        configURL: 'https://idp.example/manifest.json',
        clientId: '123',
        // Accounts endpoint can specify a 'login_hints' array for an account.
        // When RP specifies a 'exampleHint' value, only those accounts will be
        // shown to the user whose 'login_hints' array contains the 'exampleHint'
        // value
        loginHint : 'exampleHint'
      }]
    }
  });

Если ни одна учетная запись не соответствует параметру loginHint , диалоговое окно FedCM отображает запрос на вход, позволяющий пользователю войти в учетную запись поставщика идентификации (IdP), соответствующую подсказке, запрошенной поставщиком услуг идентификации (RP). Когда пользователь нажимает на подсказку, открывается диалоговое окно с URL-адресом для входа, указанным в файле конфигурации . К ссылке затем добавляются параметры запроса для входа и подсказки домена.

API подсказок домена

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

Чтобы отображать только определенные учетные записи домена, RP должен вызвать метод navigator.credentials.get() со свойством domainHint , содержащим одно из значений domain_hints , полученных из конечной точки списка учетных записей , как показано в следующем примере кода:

  return await navigator.credentials.get({
    identity: {
      providers: [{
        configURL: 'https://idp.example/manifest.json',
        clientId: 'abc',
        // Accounts endpoint can specify a 'domain_hints' array for an account.
        // When RP specifies a '@domain.example' value, only those accounts will be
        // shown to the user whose 'domain_hints' array contains the
        // '@domain.example' value
        domainHint : '@domain.example'
      }]
    }
  });

Если ни одна учетная запись не соответствует domainHint , диалоговое окно FedCM отображает запрос на вход, позволяющий пользователю войти в учетную запись IdP, соответствующую подсказке, запрошенной RP. Когда пользователь нажимает на подсказку, открывается диалоговое окно с URL-адресом для входа, указанным в файле конфигурации . К ссылке затем добавляются параметры запроса для входа и подсказки домена.

Пример запроса на вход в систему, когда ни одна учетная запись не соответствует заданному параметру domainHint.
Пример запроса на вход в систему, когда ни одна учетная запись не соответствует заданному параметру domainHint .

Для получения более подробной информации посмотрите демоверсию .

Пользовательские параметры

Функция пользовательских параметров позволяет поставщику услуг (RP) передавать дополнительные параметры типа «ключ-значение» в конечную точку проверки идентификатора . С помощью API параметров поставщики услуг могут передавать дополнительные параметры поставщику идентификации (IdP) для запроса разрешений на доступ к ресурсам, выходящих за рамки базовой авторизации. Передача дополнительных параметров может быть полезна в следующих сценариях:

  • Поставщику идентификации (IdP) необходимо динамически запрашивать дополнительные разрешения, которыми он обладает, например, доступ к платежному адресу или календарю. Пользователь может авторизовать эти разрешения через управляемый IdP пользовательский интерфейс, запускаемый с помощью функции «Продолжить» , после чего IdP передаст ему эту информацию.

Для использования API RP добавляет параметры в свойство params в виде объекта в вызове navigator.credentials.get() :

  let {token} = await navigator.credentials.get({
    identity: {
      providers: [{
        clientId: '1234',
        configURL: 'https://idp.example/fedcm.json',
        // Key/value pairs that need to be passed from the
        // RP to the IdP but that don't really play any role with
        // the browser.
        params: {
          IDP_SPECIFIC_PARAM: '1',
          foo: 'BAR'
        }
      },
    }
  });

Браузер автоматически преобразует это в POST-запрос к поставщику идентификации (IdP) с параметрами в виде единого сериализованного JSON-объекта, закодированного в URL-адресе:

  // The assertion endpoint is drawn from the config file
  POST /fedcm_assertion_endpoint HTTP/1.1
  Host: idp.example
  Origin: https://rp.example/
  Content-Type: application/x-www-form-urlencoded
  Cookie: 0x23223
  Sec-Fetch-Dest: webidentity

  // params are translated into urlencoded version of `{"IDP_SPECIFIC_PARAM":"1","foo":"bar"}`
  account_id=123&client_id=client1234&params=%22%7B%5C%22IDP_SPECIFIC_PARAM%5C%22%3A1%2C%5C%22foo%5C%22%3A%5C%22BAR%5C%22%7D%22.

Если поставщику услуг требуются дополнительные разрешения, он может предоставить ссылку для перенаправления. Например, в Node.js:

  if (rpRequestsPermissions) {
    // Response with a URL if the RP requests additional permissions
    return res.json({
      continue_on: '/example-redirect',
    });
  }

Поля

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

При регистрации пользователи увидят сообщение, уведомляющее их о том, что idp.example передаст запрошенную информацию rp.example , если пользователь решит зарегистрироваться. Если ответ от конечной точки accounts не содержит поля, запрошенного RP, текст уведомления не будет включать это поле. IdP получит все запрошенные поля от конечной точки утверждения идентификатора и решит, следует ли ему получить дополнительные разрешения пользователя для продолжения.

Диалоговое окно FedCM, содержащее следующий текст пользовательского интерфейса: «Для продолжения fedcm-idp-demo.localhost передаст ваше имя пользователя и номер телефона этому сайту».
Уведомление о раскрытии информации: Ответственный за предоставление информации просит поставщика идентификации (IdP) передавать только имя пользователя и номер телефона.

Для использования функции Fields, RP следует добавить массив fields в вызов navigator.credentials.get() . Fields могут содержать такие свойства, как name , email , tel , username или picture . В будущем его можно расширить, включив в него больше значений. Запрос с массивом fields будет выглядеть следующим образом:

   let { token } = await navigator.credentials.get({
    identity: {
      providers: [{
        // RP requests the IdP to share only username and profile picture
        fields: [ 'username', 'picture'],
        clientId: '1234',
        configURL: 'https://idp.example/fedcm.json',
      },
    }
  });

Браузер автоматически преобразует это в HTTP-запрос к конечной точке утверждения ID , который включает параметр fields указанный в RP, с полями, которые браузер раскрыл пользователю, в параметре disclosure_shown_for . Для обратной совместимости браузер также отправит disclosure_text_shown=true если текст раскрытия был показан и запрошенные поля включают все три поля : 'name' , 'email' и 'picture' . Начиная с Chrome 141, значение disclosure_text_shown не указывает, был ли текст раскрытия фактически показан пользователю.

  POST /id_assertion_endpoint HTTP/1.1
  Host: idp.example
  Origin: https://rp.example/
  Content-Type: application/x-www-form-urlencoded
  Cookie: 0x23223
  Sec-Fetch-Dest: webidentity

  // The RP only requested to share email and picture. The browser will send `disclosure_text_shown=false`, as the 'name' field value is missing
  account_id=123&client_id=client1234&disclosure_text_shown=false&fields=email,picture&disclosure_shown_for=email,picture

Если fields — пустой массив, пользовательский агент пропустит отображение информации в пользовательском интерфейсе.

Диалоговое окно пассивного режима FedCM, не отображающее сообщение пользовательского интерфейса о раскрытии информации.
В пассивном режиме сообщение об уведомлении не отображается. При нажатии кнопки сообщение об уведомлении полностью пропускается.

Это справедливо даже в том случае, если ответ от конечной точки учетных записей не содержит идентификатор клиента, совпадающий с идентификатором RP в approved_clients .

В этом случае значение параметра disclosure_text_shown , отправляемого на конечную точку подтверждения идентификатора, в теле HTTP-запроса имеет значение false:

  POST /id_assertion_endpoint HTTP/1.1
  Host: idp.example
  Origin: https://rp.example/
  Content-Type: application/x-www-form-urlencoded
  Cookie: 0x23223
  Sec-Fetch-Dest: webidentity

  account_id=123&client_id=client1234&disclosure_text_shown=false&params=%22%7B%5C%22nonce%5C%22%3A%5C%22234234%5C%22%7D%22.%0D%0A

Показать сообщение об ошибке

Если поставщик идентификации (IdP) не может выдать токен (например, если клиент не авторизован или сервер недоступен), он возвращает сообщение об ошибке. Затем поставщик идентификации (RP) может перехватить эту ошибку, и Chrome может уведомить пользователя через пользовательский интерфейс браузера, отображающий информацию об ошибке, предоставленную поставщиком идентификации.

Диалоговое окно FedCM, отображающее сообщение об ошибке после неудачной попытки входа пользователя в систему. Строка связана с типом ошибки.
Диалоговое окно FedCM, отображающее сообщение об ошибке после неудачной попытки входа пользователя в систему. Строка связана с типом ошибки .
try {
    const cred = await navigator.credentials.get({
      identity: {
        providers: [
          {
            configURL: 'https://idp.example/manifest.json',
            clientId: '1234',
          },
        ],
      }
    });
  } catch (e) {
    // Note:    In Chrome 142 and earlier, the IdentityCredentialError.error property was named IdentityCredentialError.code.
    const error = e.error;
    const url = e.url;
  }

Автоматическая повторная аутентификация пользователей после первоначальной аутентификации.

Функция автоматической повторной аутентификации FedCM (сокращенно «auto-reauthn») позволяет пользователям автоматически проходить повторную аутентификацию. Для автоматической повторной аутентификации пользователя должны быть выполнены следующие условия:

  • Пользователь ранее прошел первоначальную аутентификацию с помощью FedCM. Под «первоначальной аутентификацией» здесь понимается создание пользователем учетной записи или вход на веб-сайт RP путем первого нажатия кнопки «Продолжить как...» в диалоговом окне входа в FedCM в том же браузере.
  • У пользователя только одна учетная запись для повторной аутентификации. Если учетные записи для повторной аутентификации существуют для нескольких поставщиков идентификации, пользователь не будет автоматически повторно аутентифицирован.

Хотя явное подтверждение пользователем действий до создания федеративной учетной записи имеет смысл для предотвращения отслеживания (что является одной из главных целей FedCM), оно становится излишне громоздким после того, как пользователь прошел через него один раз: после того, как пользователь дает разрешение на обмен данными между RP и IdP, нет никакой пользы для конфиденциальности или безопасности от необходимости повторного явного подтверждения пользователем того, что он уже подтвердил ранее.

При использовании автоматической переаутентификации браузер изменяет свое поведение в зависимости от параметра, указанного вами для mediation при вызове navigator.credentials.get() .

  const cred = await navigator.credentials.get({
    identity: {
      providers: [{
        configURL: 'https://idp.example/fedcm.json',
        clientId: '1234',
      }],
    },
    mediation: 'optional', // this is the default
  });

  // `isAutoSelected` is `true` if auto-reauthn was performed.
  const isAutoSelected = cred.isAutoSelected;

Свойство mediation является свойством API управления учетными данными , оно работает так же, как и `PasswordCredential` и `FederatedCredential` , и частично поддерживается также `PublicKeyCredential` . Свойство принимает следующие четыре значения:

  • 'optional' (по умолчанию): Автоматическая повторная авторизация, если это возможно; в противном случае требуется посредничество. Рекомендуем выбрать этот параметр на странице входа в систему.
  • 'required' : Всегда требует предварительного подтверждения для продолжения, например, нажатия кнопки «Продолжить» в пользовательском интерфейсе. Выберите этот параметр, если от ваших пользователей ожидается явное предоставление разрешения каждый раз, когда им требуется аутентификация.
  • 'silent' : автоматическая повторная авторизация, если это возможно, молчаливая ошибка без необходимости посредничества, если нет. Мы рекомендуем выбирать этот параметр на страницах, отличных от страницы авторизации, но где вы хотите, чтобы пользователи оставались авторизованными — например, на странице товара на сайте доставки или на странице статьи на новостном сайте.
  • 'conditional' : Используется для WebAuthn и в данный момент недоступен для FedCM.

При таком вызове автоматическая повторная аутентификация происходит при следующих условиях:

  • FedCM доступен для использования. Например, пользователь не отключил FedCM ни глобально , ни для RP в настройках.
  • Для входа на сайт через API FedCM пользователь использовал только одну учетную запись.
  • Пользователь авторизован в системе IdP с использованием этой учетной записи.
  • Автоматическая авторизация не происходила в течение последних 10 минут.
  • После предыдущего входа в систему RP не вызывал navigator.credentials.preventSilentAccess() .

При выполнении этих условий попытка автоматической повторной аутентификации пользователя начинается сразу после вызова метода FedCM navigator.credentials.get() .

Если mediation: optional , автоматическая повторная авторизация может быть недоступна по причинам, известным только браузеру; RP может проверить, выполняется ли автоматическая повторная авторизация, изучив свойство isAutoSelected .

Это помогает оценить производительность API и соответствующим образом улучшить пользовательский опыт. Кроме того, если API недоступен, пользователю может быть предложено войти в систему с явным указанием пользователя, что представляет собой процесс с mediation: required .

Пользователь проходит автоматическую повторную аутентификацию через FedCM.

Принудительное использование механизма посредничества с помощью preventSilentAccess()

Автоматическая повторная аутентификация пользователей сразу после выхода из системы не обеспечит хорошего пользовательского опыта. Именно поэтому в FedCM предусмотрен 10-минутный период ожидания после автоматической повторной аутентификации, чтобы предотвратить такое поведение. Это означает, что автоматическая повторная аутентификация происходит не чаще одного раза в 10 минут, если пользователь не войдет в систему снова в течение 10 минут. RP должен вызывать navigator.credentials.preventSilentAccess() , чтобы явно запросить у браузера отключение автоматической повторной аутентификации, когда пользователь явно выходит из RP, например, нажав кнопку выхода.

  function signout() {
    navigator.credentials.preventSilentAccess();
    location.href = '/signout';
  }

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

Пользователи могут отключить автоматическую повторную аутентификацию в меню настроек:

  • В браузере Chrome на компьютере перейдите по адресу chrome://password-manager/settings > Автоматический вход.
  • В браузере Chrome на Android откройте Настройки > Менеджер паролей > Нажмите на значок шестеренки в правом верхнем углу > Автоматический вход.

Отключив этот переключатель, пользователь может полностью отказаться от автоматической повторной аутентификации. Этот параметр сохраняется и синхронизируется между устройствами, если пользователь вошел в учетную запись Google в экземпляре Chrome и синхронизация включена.

Отключите IdP от RP.

Если пользователь ранее входил в систему RP, используя IdP через FedCM, браузер запоминает эту связь локально в виде списка подключенных учетных записей. RP может инициировать отключение, вызвав функцию IdentityCredential.disconnect() . Эта функция может быть вызвана из фрейма RP верхнего уровня. RP необходимо передать configURL , clientId , используемый в IdP, и accountHint для отключения от IdP. AccountHint может быть произвольной строкой, если конечная точка отключения может идентифицировать учетную запись, например, адрес электронной почты или идентификатор пользователя, который не обязательно совпадает с идентификатором учетной записи, предоставленным конечной точкой списка учетных записей:

  // Disconnect an IdP account 'account456' from the RP 'https://idp.com/'. This is invoked on the RP domain.
  IdentityCredential.disconnect({
    configURL: 'https://idp.com/config.json',
    clientId: 'rp123',
    accountHint: 'account456'
  });

IdentityCredential.disconnect() возвращает Promise . Этот Promise может вызвать исключение по следующим причинам:

  • Пользователь не вошел в систему RP, используя IdP через FedCM.
  • API вызывается из iframe без политики разрешений FedCM.
  • Указанный configURL недействителен или отсутствует конечная точка отключения.
  • Проверка политики безопасности контента (CSP) завершается неудачей.
  • Имеется ожидающий рассмотрения запрос на отключение.
  • Пользователь отключил FedCM в настройках браузера.

Когда конечная точка отключения поставщика идентификации возвращает ответ , RP и IdP отключаются в браузере, и промис выполняется. Идентификаторы отключенных учетных записей указываются в ответе от конечной точки отключения .