ID プロバイダ側で FedCM を使用して ID ソリューションを実装する

FedCM の実装には、ID プロバイダ(IdP)リレーリング パーティ(RP)の両方に関するいくつかのコアステップが含まれます。RP 側で FedCM を実装する方法については、ドキュメントをご覧ください。

IdPs は、FedCM を実装するために次の手順を完了する必要があります。

well-known ファイルを作成する

トラッカーが API を不正使用しないようにするには、IdP の eTLD+1/.well-known/web-identity から well-known ファイルを提供する必要があります。

既知のファイルには、次のプロパティを含めることができます。

プロパティ 必須 説明
provider_urls 必須 IdP 構成ファイル パスの配列。accounts_endpointlogin_url が指定されている場合は無視されます(ただし、必須)。
accounts_endpoint 推奨、login_url が必要
アカウント エンドポイントの URL。これにより、各構成ファイルで同じ login_urlaccounts_endpoint URL を使用する限り、複数の構成をサポートできます。

注: このパラメータは Chrome 132 以降でサポートされています。
login_url 推奨、accounts_endpoint が必要 ユーザーが IdP にログインするためのログインページの URL。これにより、各構成ファイルで同じ login_urlaccounts_endpoint を使用する限り、複数の構成をサポートできます。

注: このパラメータは Chrome 132 以降でサポートされています。

たとえば、IdP エンドポイントが https://accounts.idp.example/ で提供されている場合、https://idp.example/.well-known/web-identity で well-known ファイルと IdP 構成ファイルを提供する必要があります。よく知られたファイルの内容の例を次に示します。

  {
    "provider_urls": ["https://accounts.idp.example/config.json"]
  }

IdP は、well-known ファイルで accounts_endpointlogin_url を指定して、IdP の複数の構成ファイルを使用できます。
この機能は、次のような場合に役立ちます。

  • IdP は、複数の異なるテスト環境と本番環境の構成をサポートする必要があります。
  • IdP は、リージョンごとに異なる構成(eu-idp.exampleus-idp.example など)をサポートする必要があります。

複数の構成をサポートするには(テスト環境と本番環境を区別する場合など)、IdP で accounts_endpointlogin_url を指定する必要があります。

  {
    // This property is required, but will be ignored when IdP supports
    // multiple configs (when `accounts_endpoint` and `login_url` are
    // specified), as long as `accounts_endpoint` and `login_url` in
    // that config file match those in the well-known file.
    "provider_urls": [ "https://idp.example/fedcm.json" ],

    // Specify accounts_endpoint and login_url properties to support
    // multiple config files.
    // Note: The accounts_endpoint and login_url must be identical
    // across all config files. Otherwise,
    // the configurations won't be supported.
    "accounts_endpoint": "https://idp.example/accounts",
    "login_url": "https://idp.example/login"
  }

IdP 構成ファイルとエンドポイントを作成する

IdP 構成ファイルには、ブラウザに必要なエンドポイントのリストが含まれています。IdP は、1 つ以上の構成ファイルと、必要なエンドポイントと URL をホストする必要があります。すべての JSON レスポンスは、application/json コンテンツ タイプで提供する必要があります。

構成ファイルの URL は、RP で実行される navigator.credentials.get() 呼び出しに指定された値によって決まります。

  const credential = await navigator.credentials.get({
    identity: {
      context: 'signup',
      providers: [{
        configURL: 'https://accounts.idp.example/config.json',
        clientId: '********',
        nonce: '******'
      }]
    }
  });
  const { token } = credential;

RP は、構成ファイルの URL を FedCM API 呼び出しに渡して、ユーザーがログインできるようにします。

  // Executed on RP's side:
  const credential = await navigator.credentials.get({
    identity: {
      context: 'signup',
      providers: [{
        // To allow users to sign in with an IdP using FedCM, RP specifies the IdP's config file URL:
        configURL: 'https://accounts.idp.example/fedcm.json',
        clientId: '********',
  });
  const { token } = credential;

ブラウザは、Origin ヘッダーまたは Referer ヘッダーのない GET リクエストで構成ファイルを取得します。リクエストに Cookie が含まれておらず、リダイレクトに従わない。これにより、リクエストを行ったユーザーと接続を試行している RP を IdP が知ることを効果的に防ぐことができます。次に例を示します。

  GET /config.json HTTP/1.1
  Host: accounts.idp.example
  Accept: application/json
  Sec-Fetch-Dest: webidentity

IdP は、JSON で応答する config エンドポイントを実装する必要があります。JSON には次のプロパティが含まれます。

プロパティ 説明
accounts_endpoint(必須) アカウント エンドポイントの URL。
accounts.include (省略可) カスタム アカウントラベル文字列。この構成ファイルを使用するときに返されるアカウントを決定します(例: "accounts": {"include": "developer"})。
IdP は、カスタム アカウントのラベル付けを次のように実装できます。

たとえば、IdP は、"accounts": {"include": "developer"} を指定して "https://idp.example/developer-config.json" 構成ファイルを実装します。また、IdP は、アカウント エンドポイントlabels パラメータを使用して、一部のアカウントに "developer" ラベルを付けます。RP が "https://idp.example/developer-config.json" 構成ファイルを指定して navigator.credentials.get() を呼び出すと、"developer" ラベルを持つアカウントのみが返されます。

注: カスタム アカウントラベルは Chrome 132 以降でサポートされています。
client_metadata_endpoint(任意) クライアント メタデータ エンドポイントの URL。
id_assertion_endpoint(必須) ID アサーション エンドポイントの URL。
disconnect(任意) 切断エンドポイントの URL。
login_url(必須) ユーザーが IdP にログインするためのログインページの URL
branding(任意) さまざまなブランディング オプションを含むオブジェクト。
branding.background_color(任意) [次の名前で続行...] ボタンの背景色を設定するブランディング オプション。関連する CSS 構文(hex-colorhsl()rgb()named-color)を使用します。
branding.color(任意) [... として続行] ボタンのテキストの色を設定するブランディング オプション。関連する CSS 構文(hex-colorhsl()rgb()named-color)を使用します。
branding.icons(任意) アイコン オブジェクトの配列。これらのアイコンはログイン ダイアログに表示されます。アイコン オブジェクトには次の 2 つのパラメータがあります。
  • url(必須): アイコン画像の URL。SVG 画像はサポートされていません。
  • size(省略可): アイコンの寸法。アプリケーションでは、正方形で単一の解像度であると想定されます。この数値は、パッシブ モードでは 25 ピクセル以上、アクティブ モードでは 40 ピクセル以上である必要があります。
modes さまざまなモードで FedCM UI を表示する方法に関する仕様を含むオブジェクト。
  • active
  • passive
modes.active 特定のモードでの FedCM の動作をカスタマイズできるプロパティを含むオブジェクト。modes.activemodes.passive の両方に次のパラメータを含めることができます。
  • supports_use_other_account: ユーザーが現在ログインしているアカウントとは異なるアカウントでログインできるかどうかを指定するブール値(IdP が複数のアカウントをサポートしている場合)。

注: [別のアカウントを使用] 機能とアクティブ モードは Chrome 132 以降でサポートされています。
modes.passive

IdP からのレスポンス本文の例を次に示します。

  {
    "accounts_endpoint": "/accounts.example",
    "client_metadata_endpoint": "/client_metadata.example",
    "id_assertion_endpoint": "/assertion.example",
    "disconnect_endpoint": "/disconnect.example",
    "login_url": "/login",
    // When RPs use this config file, only those accounts will be
    //returned that include `developer` label in the accounts endpoint.
    "accounts": {"include": "developer"},
    "modes": {
        "active": {
          "supports_use_other_account": true,
        }
    },
    "branding": {
      "background_color": "green",
      "color": "#FFEEAA",
      "icons": [{
        "url": "https://idp.example/icon.ico",
        "size": 25
      }]
    }
  }

ブラウザが構成ファイルを取得すると、以降のリクエストは IdP エンドポイントに送信されます。

IdP エンドポイント
IdP エンドポイント

別のアカウントを使用

IdP が複数のアカウントまたは既存のアカウントの置き換えをサポートしている場合、ユーザーは現在ログインしているアカウントとは異なるアカウントに切り替えることができます。

ユーザーが他のアカウントを選択できるようにするには、IdP が構成ファイルでこの機能を指定する必要があります。

  {
    "accounts_endpoint" : "/accounts.example",
    "modes": {
      "active": {
        // Allow the user to choose other account (false by default)
        "supports_use_other_account": true
      }
      // "passive" mode can be configured separately
    }
  }

アカウント エンドポイント

IdP のアカウント エンドポイントは、ユーザーが IdP にログインしているアカウントのリストを返します。IdP が複数のアカウントをサポートしている場合、このエンドポイントはログイン中のすべてのアカウントを返します。

ブラウザは、SameSite=None を含む Cookie を含む GET リクエストを送信しますが、client_id パラメータ、Origin ヘッダー、Referer ヘッダーは送信しません。これにより、ユーザーがログインしようとしている RP を IdP が知ることを効果的に防ぐことができます。次に例を示します。

  GET /accounts.example HTTP/1.1
  Host: accounts.idp.example
  Accept: application/json
  Cookie: 0x23223
  Sec-Fetch-Dest: webidentity

リクエストを受信したサーバーは、次のことを行う必要があります。

  1. リクエストに Sec-Fetch-Dest: webidentity HTTP ヘッダーが含まれていることを確認します。
  2. セッション Cookie を、すでにログインしているアカウントの ID と照合します。
  3. アカウントのリストを返します。

ブラウザは、次のプロパティを持つアカウント情報の配列を含む accounts プロパティを含む JSON レスポンスを想定しています。

プロパティ 説明
id(必須) ユーザーの一意の ID。
name(必須) ユーザーの氏名。
email(必須) ユーザーのメールアドレス。
given_name(任意) ユーザーの名前。
picture(任意) ユーザーのアバター画像の URL。
approved_clients(任意) ユーザーが登録した RP クライアント ID の配列。
login_hints(任意) IdP がアカウントの指定にサポートするすべてのフィルタタイプの配列。RP は loginHint プロパティを使用して navigator.credentials.get() を呼び出し、指定したアカウントを選択的に表示できます。
domain_hints(任意) アカウントが関連付けられているすべてのドメインの配列。RP は、domainHint プロパティを指定して navigator.credentials.get() を呼び出し、アカウントをフィルタできます。
labels(省略可) アカウントが関連付けられている文字列のカスタム アカウントラベルの配列。
IDP は、カスタム アカウントのラベル付けを次のように実装できます。
  • アカウント エンドポイントでアカウント ラベルを指定します(この labels パラメータを使用)。
  • 特定のラベルごとに構成ファイルを作成します。

たとえば、IdP は、"accounts": {"include": "developer"} を指定して https://idp.example/developer-config.json 構成ファイルを実装します。また、IdP は、 アカウント エンドポイントlabels パラメータを使用して、一部のアカウントに "developer" ラベルを付けます。RP が https://idp.example/developer-config.json 構成ファイルを指定して navigator.credentials.get() を呼び出すと、"developer" ラベルを持つアカウントのみが返されます。

カスタム アカウントラベルは、ログイン ヒントやドメイン ヒントとは異なり、IdP サーバーで完全に管理され、RP は使用する構成ファイルのみを指定します。

注: カスタム アカウントラベルは Chrome 132 以降でサポートされています。

レスポンス本文の例:

  {
    "accounts": [{
      "id": "1234",
      "given_name": "John",
      "name": "John Doe",
      "email": "john_doe@idp.example",
      "picture": "https://idp.example/profile/123",
      // Ids of those RPs where this account can be used
      "approved_clients": ["123", "456", "789"],
      // This account has 'login_hints`. When an RP calls `navigator.credentials.get()`
      // with a `loginHint` value specified, for example, `exampleHint`, only those
      // accounts will be shown to the user whose 'login_hints' array contains the `exampleHint`.
      "login_hints": ["demo1", "exampleHint"],
      // This account is labelled. IdP can implement a specific config file for a
      // label, for example, `https://idp.example/developer-config.json`. Like that
      // RPs can filter out accounts by calling `navigator.credentials.get()` with
      // `https://idp.example/developer-config.json` config file.
      "labels": ["hr", "developer"]
    }, {
      "id": "5678",
      "given_name": "Johnny",
      "name": "Johnny",
      "email": "johnny@idp.example",
      "picture": "https://idp.example/profile/456",
      "approved_clients": ["abc", "def", "ghi"],
      "login_hints": ["demo2"],
      "domain_hints": ["@domain.example"]
    }]
  }

ユーザーがログインしていない場合は、HTTP 401(未承認)で応答します。

返されたアカウント リストはブラウザで使用され、RP では使用できません。

ID 構成証明エンドポイント

IdP の ID アサーション エンドポイントは、ログイン中のユーザーのアサーションを返します。ユーザーが navigator.credentials.get() 呼び出しを使用して RP ウェブサイトにログインすると、ブラウザは、SameSite=None の Cookie と application/x-www-form-urlencoded のコンテンツ タイプを含む POST リクエストを、次の情報を付けてこのエンドポイントに送信します。

プロパティ 説明
client_id(必須) RP のクライアント ID。
account_id(必須) ログイン中のユーザーの一意の ID。
disclosure_text_shown 結果はブール値ではなく、"true" または "false" の文字列になります。次の場合に結果は "false" になります。
  • accounts エンドポイントからのレスポンスの approved_clients プロパティ リストに RP のクライアント ID が含まれていたため、開示テキストが表示されなかった場合。
  • ブラウザが過去に approved_clients がない状態で登録のタイミングを検出しているため、開示テキストが表示されなかった場合。
  • fields パラメータに 3 つのフィールド(「name」、「email」、「picture」)の 1 つ以上が含まれていない場合(例: fields=[ ]fields=['name', 'picture'])。これは、開示文字列に常に 3 つのフィールドがすべて含まれていることを想定している古い IdP 実装との下位互換性を確保するために必要です。
is_auto_selected RP で自動再認証が実行されている場合、is_auto_selected"true" を示します。それ以外の場合は "false" です。これは、セキュリティ関連の機能をより多くサポートするために役立ちます。たとえば、認証で明示的なユーザー仲介を必要とする、より高いセキュリティ ティアを希望するユーザーもいます。IdP がこのようなメディエーションなしでトークン リクエストを受信した場合、リクエストを異なる方法で処理する可能性があります。たとえば、RP が mediation: required を使用して FedCM API を再度呼び出せるように、エラーコードを返します。
fields(省略可) RP が IdP と共有する必要があるユーザー情報(「name」、「email」、「picture」)を指定する文字列の配列。
ブラウザは、次の例のように、POST リクエストで指定されたフィールドをリストする fieldsdisclosure_text_showndisclosure_shown_for を送信します。

注: Fields パラメータは Chrome 132 以降でサポートされています。
params(省略可) 追加のカスタム Key-Value パラメータを指定できる有効な JSON オブジェクト。次に例を示します。
  • scope: RP がリクエストする必要がある追加の権限を含む文字列値(例: "drive.readonly calendar.readonly"
  • nonce: この特定のリクエストに対してレスポンスが発行されることを確認するために、RP から提供されるランダムな文字列。リプレイ攻撃を防ぐことができます。
  • その他のカスタム Key-Value パラメータ。
ブラウザが POST リクエストを送信すると、params 値は JSON にシリアル化され、パーセント エンコードされます。

注: Parameters API は Chrome 132 以降でサポートされています。

HTTP ヘッダーの例:

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

  // disclosure_text_shown is set to 'false', as the 'name' field value is missing in 'fields' array
  // params value is serialized to JSON and then percent-encoded.
  account_id=123&client_id=client1234&disclosure_text_shown=false&is_auto_selected=true&params=%22%7B%5C%22nonce%5C%22%3A%5C%22nonce-value%5C%22%7D%22.%0D%0A4&disclosure_text_shown=true&fields=email,picture&disclosure_shown_for=email,picture

リクエストを受信したサーバーは、次のことを行う必要があります。

  1. CORS(クロスオリジン リソース シェアリング)を使用してリクエストに応答します。
  2. リクエストに Sec-Fetch-Dest: webidentity HTTP ヘッダーが含まれていることを確認します。
  3. Origin ヘッダーを、client_id によって決定された RP 送信元と照合します。一致しない場合は拒否します。
  4. account_id を、すでにログインしているアカウントの ID と照合します。一致しない場合は不承認にします。
  5. トークンで応答します。リクエストが拒否された場合は、エラー レスポンスで応答します。

IdP はトークンの発行方法を決定できます。通常、RP がトークンの真正性を確認できるように、アカウント ID、クライアント ID、発行元のオリジン、ノンスなどの情報で署名されます。

ブラウザは、次のプロパティを含む JSON レスポンスを想定しています。

プロパティ 説明
token トークンは、認証に関するクレームを含む文字列です。
continue_on 複数ステップのログインフローを有効にするリダイレクト URL。

返されたトークンはブラウザから RP に渡され、RP が認証を検証できます。

  {
    // IdP can respond with a token to authenticate the user
    "token": "***********"
  }

続行機能

IdP は、ID アサーション エンドポイント レスポンスでリダイレクト URL を提供して、複数ステップのログイン フローを有効にできます。これは、IdP が追加情報や権限をリクエストする必要がある場合に便利です。たとえば、次のような場合です。

  • ユーザーのサーバーサイド リソースにアクセスする権限。
  • 連絡先情報が最新であることを確認する。
  • 保護者による使用制限。

ID アサーション エンドポイントは、ID アサーション エンドポイントへの絶対パスまたは相対パスを含む continue_on プロパティを返すことができます。

  {
    // In the id_assertion_endpoint, instead of returning a typical
    // "token" response, the IdP decides that it needs the user to
    // continue on a popup window:
    "continue_on": "https://idp.example/continue_on_url"
  }

レスポンスに continue_on パラメータが含まれている場合は、新しいポップアップ ウィンドウが開き、指定されたパスにユーザーを誘導します。ユーザーが continue_on ページを操作した後、IdP はトークンを引数として渡して IdentityProvider.resolve() を呼び出す必要があります。これにより、元の navigator.credentials.get() 呼び出しからの約束を解決できます。

  document.getElementById('example-button').addEventListener('click', async () => {
    let accessToken = await fetch('/generate_access_token.cgi');
    // Closes the window and resolves the promise (that is still hanging
    // in the relying party's renderer) with the value that is passed.
    IdentityProvider.resolve(accessToken);
  });

ブラウザはポップアップを自動的に閉じて、トークンを API 呼び出し元に返します。親ウィンドウ(RP)とポップアップ ウィンドウ(IdP)が通信する唯一の方法は、1 回限りの IdentityProvider.resolve() 呼び出しです。
ユーザーがリクエストを拒否した場合、IdP は IdentityProvider.close() を呼び出してウィンドウを閉じることができます。

  IdentityProvider.close();

Continuation API を機能させるには、明示的なユーザー操作(クリック)が必要です。Continuation API がさまざまなメディエーション モードでどのように機能するかは次のとおりです。

  • パッシブ モード:
    • mediation: 'optional'(デフォルト): Continuation API は、ページ上のボタンや FedCM UI のボタンのクリックなど、ユーザー操作でのみ機能します。ユーザーの操作なしで自動再認証がトリガーされると、ポップアップ ウィンドウは開かず、Promise は拒否されます。
    • mediation: 'required': 常にユーザーに操作を求めるため、Continuation API は常に機能します。
  • アクティブ モード:
    • ユーザーによる有効化は常に必要です。Continuation API は互換性があります。

なんらかの理由でユーザーがポップアップでアカウントを変更した場合(IdP が「別のアカウントを使用する」機能を提供している場合や、委任の場合など)、resolve 呼び出しはオプションの 2 番目の引数を取り、次のようなことができます。

  IdentityProvider.resolve(token, {accountId: '1234');

エラー レスポンスを返す

id_assertion_endpoint は「error」レスポンスを返すこともできます。このレスポンスには、次の 2 つのオプション フィールドがあります。

  • code: IdP は、OAuth 2.0 で指定されたエラーリストinvalid_requestunauthorized_clientaccess_deniedserver_errortemporarily_unavailable)から既知のエラーのいずれかを選択するか、任意の文字列を使用できます。後者の場合、Chrome は一般的なエラー メッセージを含むエラー UI をレンダリングし、コードを RP に渡します。
  • url: エラーに関する情報が記載された、人間が読めるウェブページを識別して、ユーザーにエラーに関する追加情報を提供します。ブラウザは組み込みの UI で豊富なエラー メッセージを提供できないため、このフィールドはユーザーにとって便利です。たとえば、次のステップへのリンクやカスタマー サービスの連絡先情報などです。ユーザーがエラーの詳細と修正方法について詳しく知りたい場合は、ブラウザ UI から提供されたページにアクセスして詳細を確認できます。URL は、IdP configURL と同じサイトのものである必要があります。
  // id_assertion_endpoint response
  {
    "error" : {
      "code": "access_denied",
      "url" : "https://idp.example/error?type=access_denied"
    }
  }

カスタム アカウント ラベル

カスタム アカウントラベルを使用すると、IdP はユーザー アカウントにラベルをアノテーションできます。RP は、特定のラベルに configURL を指定して、特定のラベルを持つアカウントのみを取得できます。これは、RP が特定の条件でアカウントを除外する必要がある場合に便利です。たとえば、"developer""hr" などのロール固有のアカウントのみを表示する場合などです。

同様のフィルタリングは、ドメイン ヒント機能とログイン ヒント機能を使用して、navigator.credentials.get() 呼び出しで指定することでも可能です。ただし、カスタム アカウントラベルでは、構成ファイルを指定してユーザーをフィルタできます。これは、複数の configURL を使用する場合に特に便利です。カスタム アカウントラベルは、ログインやドメインヒントなど、RP ではなく IdP サーバーから提供されるという点でも異なります。

"developer" アカウントと "hr" アカウントを区別する IdP について考えてみましょう。これを実現するには、IdP が "developer""hr" の 2 つの configURL をサポートする必要があります。

  • デベロッパー構成ファイル https://idp.example/developer/fedcm.json には "developer" ラベルがあり、エンタープライズ構成ファイル https://idp.example/hr/fedcm.json には "hr" ラベルがあります。
  // The developer config file at `https://idp.example/developer/fedcm.json`
  {
    "accounts_endpoint": "https://idp.example/accounts",
    "client_metadata_endpoint": "/client_metadata",
    "login_url": "https://idp.example/login",
    "id_assertion_endpoint": "/assertion",
    "accounts": {
      // Account label
      "include": "developer"
    }
  }
  // The hr config file at `https://idp.example/hr/fedcm.json`
  {
    "accounts_endpoint": "https://idp.example/accounts",
    "client_metadata_endpoint": "/client_metadata",
    "login_url": "https://idp.example/login",
    "id_assertion_endpoint": "/assertion",
    "accounts": {
      // Account label
      "include": "hr"
    }
  }
  • このような設定では、well-known ファイルaccounts_endpointlogin_url を含めて、複数の configURL を許可する必要があります。
  {
    "provider_urls": [ "https://idp.example/fedcm.json" ],
    "accounts_endpoint": "https://idp.example/accounts",
    "login_url": "https://idp.example/login"
  }
  • 共通の IdP のアカウント エンドポイント(この例では https://idp.example/accounts)は、アカウントごとに配列にラベルが割り当てられた labels プロパティを含むアカウントのリストを返します。
  {
  "accounts": [{
    "id": "123",
    "given_name": "John",
    "name": "John Doe",
    "email": "john_doe@idp.example",
    "picture": "https://idp.example/profile/123",
    "labels": ["developer"]
    }], [{
    "id": "4567",
    "given_name": "Jane",
    "name": "Jane Doe",
    "email": "jane_doe@idp.example",
    "picture": "https://idp.example/profile/4567",
    "labels": ["hr"]
    }]
  }

RP が "hr" ユーザーのログインを許可する場合は、navigator.credentials.get() 呼び出しで configURL https://idp.example/hr/fedcm.json を指定できます。

  let { token } = await navigator.credentials.get({
    identity: {
      providers: [{
        clientId: '1234',
        nonce: '234234',
        configURL: 'https://idp.example/hr/fedcm.json',
      },
    }
  });

その結果、ユーザーがログインできるのはアカウント ID 4567 のみになります。アカウント ID 123 はブラウザによって非表示になっており、このサイトの IdP でサポートされていないアカウントがユーザーに提供されることはありません。

  • ラベルは文字列です。labels 配列または include フィールドに文字列以外のものが含まれている場合、その値は無視されます。
  • configURL でラベルが指定されていない場合、すべてのアカウントが FedCM アカウント選択ツールに表示されます。
  • アカウントにラベルが指定されていない場合、configURL にもラベルが指定されていない場合にのみ、アカウント選択ツールに表示されます。
  • パッシブ モードでリクエストされたラベルに一致するアカウントがない場合(ドメインヒント機能と同様)、FedCM ダイアログにログイン プロンプトが表示され、ユーザーは IdP アカウントにログインできます。アクティブ モードでは、ログイン ポップアップ ウィンドウが直接開きます。

エンドポイントの切断

IdentityCredential.disconnect() を呼び出すと、ブラウザは、SameSite=None を含む Cookie と application/x-www-form-urlencoded のコンテンツ タイプを持つクロスオリジン POST リクエストを、次の情報を含めてこの切断エンドポイントに送信します。

プロパティ 説明
account_hint IdP アカウントのヒント。
client_id RP のクライアント ID。
  POST /disconnect.example HTTP/1.1
  Host: idp.example
  Origin: rp.example
  Content-Type: application/x-www-form-urlencoded
  Cookie: 0x123
  Sec-Fetch-Dest: webidentity

  account_hint=account456&client_id=rp123

リクエストを受信したサーバーは、次のことを行う必要があります。

  1. CORS(クロスオリジン リソース シェアリング)を使用してリクエストに応答します。
  2. リクエストに Sec-Fetch-Dest: webidentity HTTP ヘッダーが含まれていることを確認します。
  3. Origin ヘッダーを、client_id によって決定された RP 送信元と照合します。一致しない場合は拒否します。
  4. account_hint を、すでにログインしているアカウントの ID と照合します。
  5. ユーザー アカウントと RP の接続を解除します。
  6. 特定されたユーザー アカウント情報を JSON 形式でブラウザに返します。

レスポンスの JSON ペイロードの例を次に示します。

  {
    "account_id": "account456"
  }

代わりに、IdP がブラウザで RP に関連付けられているすべてのアカウントの接続を解除することを希望する場合は、アカウント ID と一致しない文字列("*" など)を渡します。

クライアント メタデータ エンドポイント

IdP のクライアント メタデータ エンドポイントは、RP のプライバシー ポリシー、利用規約、ロゴアイコンなどのリレーリング パーティのメタデータを返します。RP は、プライバシー ポリシーと利用規約へのリンクを事前に IdP に提供する必要があります。これらのリンクは、ユーザーが IdP で RP にまだ登録していない場合に、ログイン ダイアログに表示されます。

ブラウザは、Cookie なしで client_id navigator.credentials.get を使用して GET リクエストを送信します。次に例を示します。

  GET /client_metadata.example?client_id=1234 HTTP/1.1
  Host: accounts.idp.example
  Origin: https://rp.example/
  Accept: application/json
  Sec-Fetch-Dest: webidentity

リクエストを受信したサーバーは、次のことを行う必要があります。

  1. client_id の RP を特定します。
  2. クライアント メタデータで応答します。

クライアント メタデータ エンドポイントのプロパティには、次のようなものがあります。

プロパティ 説明
privacy_policy_url(任意) RP のプライバシー ポリシーの URL。
terms_of_service_url(任意) RP 利用規約の URL。
icons(任意) オブジェクトの配列([{ "url": "https://rp.example/rp-icon.ico", "size": 40}] など)

ブラウザは、エンドポイントから JSON レスポンスを想定しています。

  {
    "privacy_policy_url": "https://rp.example/privacy_policy.html",
    "terms_of_service_url": "https://rp.example/terms_of_service.html",
    "icons": [{
          "url": "https://rp.example/rp-icon.ico",
          "size": 40
      }]
  }

返されたクライアント メタデータはブラウザによって使用され、RP では使用できません。

ログイン URL

このエンドポイントは、ユーザーが IdP にログインできるようにするために使用されます。

Login Status API を使用する場合、IdP はユーザーのログイン ステータスをブラウザに通知する必要があります。ただし、セッションの有効期限が切れた場合など、ステータスが同期されていない可能性があります。このようなシナリオでは、ブラウザは、idp 構成ファイルlogin_url で指定されたログインページ URL を使用して、ユーザーが IdP に動的にログインできるようにします。

次の画像に示すように、FedCM ダイアログにログインを促すメッセージが表示されます。

A IdP へのログインを促す FedCM ダイアログ。

ユーザーが [続行] ボタンをクリックすると、ブラウザで IdP のログインページのポップアップ ウィンドウが開きます。

FedCM ダイアログの例。
IdP へのログイン ボタンをクリックした後に表示されるダイアログの例。

このダイアログは、ファーストパーティ Cookie が設定された通常のブラウザ ウィンドウです。ダイアログ内で発生するすべての処理は IdP に委ねられます。また、RP ページへのクロスオリジン通信リクエストを実行するためのウィンドウ ハンドルは使用できません。ユーザーがログインすると、IdP は次の処理を行う必要があります。

  • Set-Login: logged-in ヘッダーを送信するか、navigator.login.setStatus("logged-in") API を呼び出して、ユーザーがログインしたことをブラウザに通知します。
  • IdentityProvider.close() を呼び出してダイアログを閉じます。
ユーザーは、FedCM を使用して IdP にログインした後に RP にログインします。

ユーザーのログイン ステータスをブラウザに通知する

Login Status API は、ウェブサイト(特に IdP)が IdP でのユーザーのログイン ステータスをブラウザに通知するメカニズムです。この API を使用すると、ブラウザは IdP への不要なリクエストを減らし、潜在的なタイミング攻撃を軽減できます。

IdP は、ユーザーが IdP にログインしたとき、またはユーザーがすべての IdP アカウントからログアウトしたときに、HTTP ヘッダーを送信するか、JavaScript API を呼び出して、ユーザーのログイン ステータスをブラウザに通知できます。ブラウザは、IdP ごとに(構成 URL で識別される)ログイン状態を表す 3 値の変数を保持します。値は次のとおりです。

  • logged-in
  • logged-out
  • unknown(デフォルト)
ログイン状態 説明
logged-in ユーザーのログイン ステータスが logged-in に設定されている場合、FedCM を呼び出す RP は IdP のアカウント エンドポイントにリクエストを行い、利用可能なアカウントを FedCM ダイアログでユーザーに表示します。
logged-out ユーザーのログイン ステータスが logged-out の場合、FedCM の呼び出しは、IdP のアカウント エンドポイントにリクエストを送信せずに、サイレント エラーになります。
unknown(デフォルト) unknown ステータスは、IdP が Login Status API を使用してシグナルを送信する前に設定されます。ステータスが unknown の場合、ブラウザは IdP のアカウント エンドポイントにリクエストを行い、アカウント エンドポイントからのレスポンスに基づいてステータスを更新します。

ユーザーがログインしたことを通知するには、トップレベル ナビゲーションまたは IdP 送信元の同一サイトのサブリソース リクエストで Set-Login: logged-in HTTP ヘッダーを送信します。

  Set-Login: logged-in

または、トップレベル ナビゲーションの IdP オリジンから JavaScript メソッド navigator.login.setStatus('logged-in') を呼び出します。

  navigator.login.setStatus('logged-in')

ユーザーのログイン ステータスは logged-in に設定されます。

ユーザーがすべてのアカウントからログアウトしたことを通知するには、最上位のナビゲーションまたは IdP オリジンの同一サイトのサブリソース リクエストで Set-Login: logged-out HTTP ヘッダーを送信します。

  Set-Login: logged-out

または、最上位のナビゲーションの IdP オリジンから JavaScript API navigator.login.setStatus('logged-out') を呼び出します。

  navigator.login.setStatus('logged-out')

ユーザーのログイン ステータスは logged-out に設定されます。

unknown ステータスは、IdP が Login Status API を使用してシグナルを送信する前に設定されます。ブラウザは IdP のアカウント エンドポイントにリクエストを行い、アカウント エンドポイントからのレスポンスに基づいてステータスを更新します。

  • エンドポイントが有効なアカウントのリストを返す場合は、ステータスを logged-in に更新し、FedCM ダイアログを開いてアカウントを表示します。
  • エンドポイントからアカウントが返されなかった場合は、ステータスを logged-out に更新し、FedCM 呼び出しを失敗させます。

ユーザーが動的ログインフローを使用してログインできるようにする

IdP がユーザーのログイン ステータスをブラウザに通知し続けても、セッションの有効期限が切れたときなど、同期がずれる可能性があります。ログイン ステータスが logged-in の場合、ブラウザは認証情報付きのリクエストをアカウント エンドポイントに送信しようとしますが、セッションが利用できなくなったため、サーバーからアカウントが返されません。このようなシナリオでは、ブラウザはポップアップ ウィンドウからユーザーが IdP にログインできるように動的に設定できます

次のステップ

RP に FedCM を実装し、JavaScript SDK を配布します。セルフ実装の必要がないため、RP を最新の状態に保つことができます。
環境を設定し、実装をデバッグする方法を学びます。