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

Проверяющим сторонам (RP) необходимо выполнить следующие шаги, чтобы включить 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 может поддерживать несколько IdP, указав массив из нескольких поставщиков удостоверений в одном вызове 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 поддерживает различные конфигурации UX-режимов . Пассивный режим используется по умолчанию, и разработчикам не нужно его настраивать.

Чтобы использовать 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'
      }
    });
  }

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

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

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

Вызов 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 может рекомендовать пользователю, какую учётную запись ему следует использовать. Это может быть полезно для повторной аутентификации пользователей, которые не уверены, какую учётную запись они использовали ранее.

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 отображает запрос на вход, позволяющий пользователю войти в учётную запись поставщика удостоверений, соответствующую подсказке, запрошенной проверяющей стороной. При нажатии на подсказку открывается всплывающее окно с 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 параметров RP-серверы могут передавать дополнительные параметры IdP для запроса разрешений на доступ к ресурсам, выходящим за рамки простого входа. Передача дополнительных параметров может быть полезна в следующих сценариях:

  • RP должен динамически запрашивать дополнительные разрешения, имеющиеся у 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 с параметрами в виде одного URL-кодированного сериализованного объекта JSON:

  // 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.

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

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

Поля

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

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

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

Чтобы использовать функцию «Поля», RP должен добавить массив fields в вызов navigator.credentials.get() . Поля могут содержать такие свойства, как 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-запрос к конечной точке утверждения идентификатора , включающий параметр 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 , отправленный в конечную точку утверждения идентификатора, имеет значение false в теле HTTP:

  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&nonce=234234&disclosure_text_shown=false

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

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

Диалоговое окно FedCM с сообщением об ошибке после неудачной попытки входа пользователя. Строка связана с типом ошибки.
Диалоговое окно FedCM с сообщением об ошибке после неудачной попытки входа пользователя. Строка связана с типом ошибки .
  try {
    const cred = await navigator.credentials.get({
      identity: {
        providers: [
          {
            configURL: 'https://idp.example/manifest.json',
            clientId: '1234',
          },
        ],
      }
    });
  } catch (e) {
    const code = e.code;
    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 > Автоматический вход.
  • В Android Chrome откройте «Настройки» > «Менеджер паролей » > нажмите на шестеренку в правом верхнем углу > «Автоматический вход».

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

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

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

  // 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 и поставщик удостоверений отключаются в браузере, и обещание выполняется. Идентификаторы отключённых учётных записей указываются в ответе конечной точки отключения .

Следующие шаги

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