リレーリング パーティ側で FedCM を使用して ID ソリューションを実装する

証明書利用者(RP)は、サイトで FedCM を有効にするために、次の手順を完了する必要があります。

Relying Party で FedCM API を呼び出す

IdP の構成とエンドポイントが利用可能になると、RP は navigator.credentials.get() を呼び出して、ユーザーが IdP を使用して RP にログインできるようにリクエストできます。

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
  }

ユーザーが FedCM を使用して RP の IdP にログインできるようにするには、RP が navigator.credentials.get() を呼び出すことができます。Chrome 136 以降では、RP は 1 回の navigator.credentials.get() 呼び出しで複数の ID プロバイダの配列を指定することで、複数の IdP をサポートできます。例:

  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
    }

IdP1IdP2 でログインして、複数の IdP 機能を試します。

コンテキスト プロパティ

RP は、オプションの context プロパティを使用して、FedCM ダイアログ UI の文字列(「rp.example にログイン…」、「idp.example を使用…」など)を変更し、たとえば、事前定義された認証コンテキストに対応できます。context プロパティには次の値を指定できます。

  • signin(デフォルト)
  • signup
  • use
FedCM ダイアログの UI コンポーネントを説明する図: 左上にアイコンが表示されています。アイコンの右側には、コンテキスト コンポーネントが表示され、「IdP で RP にログイン」というメッセージが表示されます。下部には、カスタムのテキストと背景色の [続行] ボタンがあります。
FedCM ダイアログにブランディングを適用する方法

たとえば、contextuse に設定すると、次のメッセージが表示されます。

カスタマイズされたコンテキスト メッセージを表示する FedCM ダイアログ: コンテキスト メッセージは、FedCM での [ログイン] ではなく、FedCM での [使用] と表示されています。
カスタマイズされたコンテキスト メッセージを表示する FedCM ダイアログ。

ブラウザは、アカウント リスト エンドポイントからのレスポンスに approved_clients が存在するかどうかによって、登録とログインのユースケースを異なる方法で処理します。ユーザーがすでに RP に登録している場合、ブラウザには開示テキスト「To continue with ....」は表示されません。

providers プロパティは、次のプロパティを持つ IdentityProvider オブジェクトの配列を受け取ります。

Providers プロパティ

providers プロパティは、次のプロパティを持つ IdentityProvider オブジェクトの配列を受け取ります。

プロパティ 説明
configURL(必須) IdP 構成ファイルのフルパス。
clientId(必須) IdP によって発行された RP のクライアント識別子。
loginHint(任意) アカウント エンドポイントから提供される login_hints 値のいずれかを指定することで、FedCM ダイアログで指定されたアカウントが選択的に表示されます。
domainHint(任意) アカウント エンドポイントから提供される domain_hints 値のいずれかを指定することで、FedCM ダイアログで指定されたアカウントが選択的に表示されます。
mode(任意) FedCM の UI モードを指定する文字列。次のいずれかの値を指定できます。
  • "active": FedCM プロンプトは、ユーザー操作(ボタンのクリックなど)によって開始される必要があります。
  • "passive": ユーザーの直接操作なしで FedCM プロンプトが開始されます。
アクティブ モードとパッシブ モードの違いについて詳しくは、概要ページをご覧ください。

注: mode パラメータは Chrome 132 以降でサポートされています。
fields(任意) RP が IdP に共有を求めるユーザー情報を指定する文字列の配列。次のフィールドは必要に応じて指定できます。
  • "name"
  • "username"
  • "email"
  • "tel"
  • "picture"
注: Fields API は Chrome 132 以降でサポートされています。"username" フィールドと "tel" フィールドは Chrome 141 以降でサポートされています。
params(任意) 追加の Key-Value パラメータを指定できるカスタム オブジェクト:
  • scope: RP がリクエストする必要がある追加の権限を含む文字列値(例: "drive.readonly calendar.readonly"
  • nonce: この特定のリクエストに対してレスポンスが発行されるようにするためのランダムな文字列。リプレイ攻撃を防ぎます。
  • その他のカスタム Key-Value パラメータ。

注: 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'
      }
    });
  }

デモでアクティブ モードをお試しください。

アクティブ モードのカスタム アイコン

アクティブ モードでは、IdP は RP の公式ロゴアイコンを クライアント メタデータ エンドポイントのレスポンスに直接含めることができます。RP は、ブランディング データを事前に提供する必要があります。

クロスオリジンの iframe 内から FedCM を呼び出す

親フレームで許可されている場合、identity-credentials-get 権限ポリシーを使用して、クロスオリジン iframe 内から FedCM を呼び出すことができます。そのためには、次のように 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")

Permissions Policy の仕組みについて詳しくは、Permissions Policy を使用してブラウザ機能を制御するをご覧ください。

ログイン ヒント 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 ダイアログにログイン プロンプトが表示され、ユーザーは RP がリクエストしたヒントに一致する IdP アカウントにログインできます。ユーザーがプロンプトをタップすると、構成ファイルで指定されたログイン URL を含むダイアログ ウィンドウが開きます。リンクには、ログイン ヒントとドメイン ヒントのクエリ パラメータが付加されます。

Domain Hint API

RP は、特定のドメインに関連付けられたアカウントのみを選択的に表示できます。これは、企業ドメインに制限されている RP に役立ちます。

特定のドメイン アカウントのみを表示するには、次のコードサンプルに示すように、RP は アカウント リスト エンドポイントから取得した domain_hints 値のいずれかを domainHint プロパティに指定して navigator.credentials.get() を呼び出す必要があります。

  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 ダイアログにログイン プロンプトが表示され、ユーザーは RP がリクエストしたヒントに一致する IdP アカウントにログインできます。ユーザーがプロンプトをタップすると、構成ファイルで指定されたログイン URL を含むダイアログ ウィンドウが開きます。リンクには、ログイン ヒントとドメイン ヒントのクエリ パラメータが付加されます。

domainHint に一致するアカウントがない場合のログイン プロンプトの例。
domainHint に一致するアカウントがない場合のログイン プロンプトの例。

詳しくは、デモをご覧ください。

カスタム パラメータ

カスタム パラメータ機能を使用すると、RP は ID アサーション エンドポイントに追加の Key-Value パラメータを提供できます。パラメータ API を使用すると、RP は追加のパラメータを IdP に渡して、基本的なログイン以外のリソースに対する権限をリクエストできます。追加のパラメータを渡すことは、次のようなシナリオで役立ちます。

  • RP は、請求先住所やカレンダーへのアクセスなど、IdP が持つ追加の権限を動的にリクエストする必要があります。ユーザーは、Continue on 機能を使用して起動される IdP 制御の UX フローを通じてこれらの権限を承認できます。その後、IdP はこの情報を共有します。

API を使用するには、RP は navigator.credentials.get() 呼び出しで params プロパティにオブジェクトとしてパラメータを追加します。

  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'
        }
      },
    }
  });

ブラウザは、これを自動的に IdP への POST リクエストに変換し、パラメータを単一の 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 ダイアログの開示 UI に含まれます。

登録するユーザーには、登録を選択した場合、idp.example がリクエストされた情報を rp.example と共有するという通知メッセージが表示されます。アカウント エンドポイントからのレスポンスに RP がリクエストしたフィールドが含まれていない場合、開示テキストにこのフィールドは含まれません。IdP は、ID アサーション エンドポイントからリクエストされたすべてのフィールドを学習し、続行するためにユーザー権限をさらに収集する必要があるかどうかを判断します。

FedCM ダイアログ。次の開示 UI テキストが含まれています: 「続行すると、fedcm-idp-demo.localhost からこのサイトにユーザー名と電話番号が共有されます。」。
開示メッセージ: RP は IdP に対して、ユーザー名と電話番号のみを共有するようリクエストします。

フィールド機能を使用するには、RP は navigator.credentials.get() 呼び出しに fields 配列を追加する必要があります。フィールドには、nameemailtelusernamepicture などのプロパティを含めることができます。この値は、今後さらに追加される可能性があります。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',
      },
    }
  });

ブラウザは、RP が指定した fields パラメータと、ブラウザがユーザーに開示したフィールドを disclosure_shown_for パラメータに含んだ ID アサーション エンドポイントへの HTTP リクエストに自動的に変換します。下位互換性のため、開示テキストが表示され、リクエストされたフィールドに 3 つのフィールドすべて'name''email''picture')が含まれている場合、ブラウザは disclosure_text_shown=true も送信します。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 が空の配列の場合、ユーザー エージェントは開示 UI をスキップします。

開示 UI メッセージが表示されない FedCM パッシブ モードのダイアログ。
パッシブ モードでは開示メッセージは表示されません。ボタンフローでは、開示 UI は完全にスキップされます。

これは、アカウント エンドポイントからのレスポンスに approved_clients の RP と一致するクライアント ID が含まれていない場合でも同様です。

この場合、ID アサーション エンドポイントに送信される 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&nonce=234234&disclosure_text_shown=false

エラー メッセージを表示する

クライアントが承認されていない場合や、サーバーが一時的に利用できない場合など、正当な理由で IdP がトークンを発行できないことがあります。IdP が「エラー」レスポンスを返した場合、RP はそれをキャッチできます。Chrome は、IdP から提供されたエラー情報を含むブラウザ UI を表示して、ユーザーに通知できます。

ユーザーのログイン試行が失敗した後にエラー メッセージを表示する 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 の自動再認証(略して「自動再認証」)を使用すると、ユーザーは自動的に再認証できます。ユーザーを自動的に再認証するには、次の条件を満たす必要があります。

  • ユーザーが FedCM を使用して初回認証を完了している。ここで「初回認証」とは、ユーザーが同じブラウザ インスタンスで FedCM のログイン ダイアログの [Continue as...] ボタンを初めてタップして、アカウントを作成するか、RP のウェブサイトにログインすることを意味します。
  • お客様が復元できるアカウントは 1 つのみです。複数の IdP に戻りアカウントが存在する場合、ユーザーは自動的に再認証されません。

明示的なユーザー エクスペリエンスは、ユーザーがフェデレーション アカウントを作成する前にトラッキングを防ぐ(FedCM の主な目標の 1 つ)ために理にかなっていますが、ユーザーが一度経験した後は不必要に面倒になります。ユーザーが RP と IdP 間の通信を許可する権限を付与した後、以前に承認したことについて別の明示的なユーザー確認を強制しても、プライバシーやセキュリティ上のメリットはありません。

自動再認証では、navigator.credentials.get() を呼び出すときに mediation に指定したオプションに応じて、ブラウザの動作が変化します。

  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 のプロパティで、PasswordCredentialFederatedCredential の場合と同じように動作します。また、PublicKeyCredential でも部分的にサポートされています。このプロパティには次の 4 つの値を指定できます。

  • 'optional'(デフォルト): 可能であれば自動再認証を行い、不可能であれば仲介を必要とします。ログイン ページでこのオプションを選択することをおすすめします。
  • 'required': 続行するには常に仲介が必要です(UI の [続行] ボタンをクリックするなど)。ユーザーが認証を必要とするたびに明示的に権限を付与することが想定される場合は、このオプションを選択します。
  • 'silent': 可能であれば自動再認証を行い、可能でなければ仲介を必要とせずにサイレントに失敗します。このオプションは、専用のログインページ以外のページで、ユーザーのログイン状態を維持したい場合に選択することをおすすめします。たとえば、配送ウェブサイトの商品ページやニュース ウェブサイトの記事ページなどです。
  • 'conditional': WebAuthn に使用されます。現時点では FedCM では使用できません。

この呼び出しでは、次の条件で自動再認証が行われます。

  • FedCM を使用できます。たとえば、ユーザーが設定で FedCM をグローバルに無効にしていないか、RP に対して無効にしていない場合です。
  • ユーザーが FedCM API を使用してこのブラウザでウェブサイトにログインしたアカウントは 1 つだけです。
  • ユーザーがそのアカウントで IdP にログインしている。
  • 過去 10 分以内に自動再認証が行われていない。
  • RP が、前回のログイン後に navigator.credentials.preventSilentAccess() を呼び出していない。

これらの条件が満たされると、FedCM navigator.credentials.get() が呼び出された直後に、ユーザーの自動再認証が試行されます。

mediation: optional の場合、ブラウザのみが知っている理由により、自動再認証が利用できないことがあります。RP は、isAutoSelected プロパティを調べることで、自動再認証が実行されたかどうかを確認できます。

これは、API のパフォーマンスを評価し、それに応じて UX を改善するのに役立ちます。また、利用できない場合は、ユーザーに明示的なユーザー メディエーション(mediation: required を含むフロー)でログインするよう求めるメッセージが表示されることがあります。

FedCM を介して自動再認証を行うユーザー。

preventSilentAccess() でメディエーションを適用する

ユーザーがログアウトした直後に自動的に再認証を行うと、ユーザー エクスペリエンスが低下します。そのため、FedCM では、自動再認証後に 10 分間の静止期間を設けて、この動作を防いでいます。つまり、ユーザーが 10 分以内に再ログインしない限り、自動再認証は 10 分ごとに 1 回まで行われます。RP は、ユーザーが RP から明示的にログアウトした(ログアウト ボタンをクリックするなど)ときに、ブラウザに自動再認証を無効にするよう明示的にリクエストするために navigator.credentials.preventSilentAccess() を呼び出す必要があります。

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

ユーザーは設定で自動再認証をオプトアウトできます

ユーザーは設定メニューから自動再認証をオプトアウトできます。

  • パソコン版 Chrome で、chrome://password-manager/settings > [自動的にログイン] に移動します。
  • Android 版 Chrome で、[設定] > [パスワード マネージャー] を開き、右上にある歯車アイコン > [自動ログイン] をタップします。

切り替えを無効にすると、ユーザーは自動再認証の動作を完全に無効にできます。この設定は、ユーザーが Chrome インスタンスで Google アカウントにログインし、同期が有効になっている場合、デバイス間で保存および同期されます。

IdP と RP の接続を解除する

ユーザーが FedCM を介して IdP を使用して RP に以前にログインしている場合、その関係は接続済みアカウントのリストとしてブラウザによってローカルに記憶されます。RP は、IdentityCredential.disconnect() 関数を呼び出すことで切断を開始できます。この関数は、最上位の RP フレームから呼び出すことができます。RP は、configURL、IdP で使用する clientId、IdP を切断するための accountHint を渡す必要があります。アカウントのヒントは、切断エンドポイントがアカウントを識別できる限り、任意の文字列にできます。たとえば、アカウント リスト エンドポイントが提供したアカウント ID と必ずしも一致しないメールアドレスやユーザー ID などです。

  // 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 は、次の理由で例外をスローする可能性があります。

  • ユーザーが FedCM を介して IdP を使用して RP にログインしていない。
  • API は FedCM 権限ポリシーなしで iframe 内から呼び出されます。
  • configURL が無効であるか、切断エンドポイントがありません。
  • コンテンツ セキュリティ ポリシー(CSP)チェックが失敗します。
  • 保留中の接続解除リクエストがあります。
  • ユーザーがブラウザの設定で FedCM を無効にしている。

IdP の切断エンドポイントがレスポンスを返すと、ブラウザで RP と IdP が切断され、Promise が解決されます。接続解除されたアカウントの ID は、接続解除エンドポイントからのレスポンスで指定されます。