Chrome で WebAuthn のヒント、関連オリジン リクエスト、JSON シリアル化を導入

Chrome 128 と 129 では、パスキーベースの認証システムを構築するための基盤となる API である WebAuthn の新しい機能が導入されます。

  • ヒント: ヒントを使用すると、信頼できる当事者(RP)はブラウザの WebAuthn UI をより適切に制御できます。セキュリティ キーを使用する企業ユーザーに特に便利です。
  • 関連するオリジン リクエスト: 関連するオリジン リクエストを使用すると、RP は複数のドメインでパスキーを有効にできます。複数のサイトを所有している場合は、ユーザーがサイト間でパスキーを再利用できるようにして、ログインの手間を省くことができます。
  • JSON シリアル化: JSON シリアル化 API を使用すると、WebAuthn API との間で渡されるオプションと認証情報をエンコードおよびデコードすることで、RP のフロントエンド コードを簡素化できます。

ヒント

hints により、リライング パーティ(RP)はパスキーの作成またはパスキーによる認証の UI 設定を指定できるようになりました。

以前は、ユーザーがパスキーの作成または認証に使用できる認証システムを RP が制限する必要がある場合、authenticatorSelection.authenticatorAttachment を使用して "platform" または "cross-platform" を指定できました。認証システムはそれぞれ、プラットフォーム認証システムまたはローミング認証システムに制限します。hints を使用すると、この仕様をより柔軟に指定できます。

RP は、PublicKeyCredentialCreationOptions または PublicKeyCredentialRequestOptions のオプションの hints を使用して、"security-key""client-device""hybrid" を配列内の優先順位で指定できます。

次の例は、"security-key" をヒントとして "cross-platform" 認証システムを優先する認証情報作成リクエストです。これにより、エンタープライズ ユーザー向けにセキュリティ キーに重点を置いた UI を Chrome に表示するよう指示します。

const credential = await navigator.credentials.create({
  publicKey: {
    challenge: *****,
    hints: ['security-key'],
    authenticatorSelection: {
      authenticatorAttachment: 'cross-platform'
    }
  }
});
ヒントとして「security-key」を指定すると、ブラウザにセキュリティ キーにフォーカスされたダイアログが表示されます。
ヒントとして「security-key」を指定すると、ブラウザにセキュリティ キーにフォーカスされたダイアログが表示されます。

RP がクロスデバイス認証シナリオを優先する場合は、"hybrid" をヒントとして "cross-platform" 認証システムを優先する認証リクエストを送信できます。

const credential = await navigator.credentials.create({
  publicKey: {
    challenge: *****,
    residentKey: true,
    hints: ['hybrid']
    authenticatorSelection: {
      authenticatorAttachment: 'cross-platform'
    }
  }
});
ヒントとして「hybrid」を指定すると、ブラウザにはクロスデバイス ログインにフォーカスしたダイアログが表示されます。
ヒントとして「hybrid」を指定すると、ブラウザにクロスデバイス ログインにフォーカスしたダイアログが表示されます。

関連オリジン リクエストを使用すると、RP は複数のドメインからパスキーを使用できるようにできます。一元化されたログイン エクスペリエンスを構築し、連携プロトコルを使用することは、ほとんどのサイトに推奨されるソリューションです。ただし、複数のドメインを所有していて、連携できない場合は、関連するオリジンが解決策になる可能性があります。

すべての WebAuthn リクエストでリレーリング パーティ ID(RP ID)を指定する必要があります。すべてのパスキーは単一の RP ID に関連付けられます。従来、オリジンはドメインに基づいて RP ID のみを指定できました。この場合、www.example.co.uk は RP ID として example.co.uk を指定できますが、example.com を指定することはできません。関連オリジン リクエストでは、対象ドメインの /.well-known/webauthn にあるよく知られた JSON ファイルを取得することで、申告された RP ID を検証できます。したがって、example.com が次の形式で指定されている場合、example.co.uk(および example.inexample.de など)はすべて example.com の RP ID を使用できます。

URL: https://example.com/.well-known/webauthn

{
  "origins": [
    "https://example.co.uk",
    "https://example.de",
    "https://example.sg",
    "https://example.net",
    "https://exampledelivery.com",
    "https://exampledelivery.co.uk",
    "https://exampledelivery.de",
    "https://exampledelivery.sg",
    "https://myexamplerewards.com",
    "https://examplecars.com"
  ]
}

関連オリジン リクエストを設定する方法については、関連オリジン リクエストを使用してサイト間でパスキーの再利用を許可するをご覧ください。

JSON シリアル化

WebAuthn のリクエスト オブジェクトとレスポンス オブジェクトには、認証情報 ID、ユーザー ID、チャレンジなど、ArrayBuffer 内の未加工バイナリ データを含む複数のフィールドがあります。ウェブサイトが JSON を使用してこのデータをサーバーと交換する場合は、まずバイナリデータを Base64URL などでエンコードする必要があります。これにより、ウェブサイトでパスキーの使用を開始するデベロッパーにとって、不要な複雑さが追加されます。

WebAuthn に、PublicKeyCredentialCreationOptionsPublicKeyCredentialRequestOptions の WebAuthn リクエスト オブジェクトを JSON から直接解析し、PublicKeyCredential レスポンスを JSON に直接シリアル化する API が追加されました。未加工のバイナリ データを伝送する ArrayBuffer 値のフィールドはすべて、Base64URL でエンコードされた値との間で自動的に変換されます。これらの API は Chrome 129 以降で使用できます。

パスキーを作成する前に、JSON エンコードされた PublicKeyCredentialCreationOptions オブジェクトをサーバーから取得し、PublicKeyCredential.parseCreationOptionsFromJSON() を使用してデコードします。

対応ブラウザ

  • Chrome: 129。
  • Edge: 129。
  • Firefox: 119.
  • Safari: サポートされていません。

ソース

export async function registerCredential() {

  // Fetch encoded `PublicKeyCredentialCreationOptions`
  // and JSON decode it.
  const options = await fetch('/auth/registerRequest').json();

  // Decode `PublicKeyCredentialCreationOptions` JSON object
  const decodedOptions = PublicKeyCredential.parseCreationOptionsFromJSON(options);  

  // Invoke the WebAuthn create() function.
  const cred = await navigator.credentials.create({
    publicKey: decodedOptions,
  });
  ...

パスキーを作成したら、toJSON() を使用して生成された認証情報をエンコードし、サーバーに送信できるようにします。

対応ブラウザ

  • Chrome: 129。
  • Edge: 129。
  • Firefox: 119.
  • Safari: サポートされていません。

ソース

  ...
  const cred = await navigator.credentials.create({
    publicKey: options,
  });

  // Encode the credential to JSON and stringify
  const credential = JSON.stringify(cred.toJSON());

  // Send the encoded credential to the server
  await fetch('/auth/registerResponse', credential);
  ...

パスキーで認証する前に、JSON エンコードされた PublicKeyRequestCreationOptions をサーバーから取得し、PublicKeyCredential.parseRequestOptionsFromJSON() を使用してデコードします。

対応ブラウザ

  • Chrome: 129。
  • Edge: 129。
  • Firefox: 119.
  • Safari: サポートされていません。

ソース

export async function authenticate() {

  // Fetch encoded `PublicKeyCredentialRequestOptions`
  // and JSON decode it.
  const options = await fetch('/auth/signinRequest').json();

  // Decode `PublicKeyCredentialRequestOptions` JSON object
  const decodedOptions = PublicKeyCredential.parseRequestOptionsFromJSON(options);

  // Invoke the WebAuthn get() function.
  const cred = await navigator.credentials.get({
    publicKey: options
  });
  ...

パスキーで認証したら、toJSON() メソッドを使用して結果の認証情報をエンコードし、サーバーに送信できるようにします。

対応ブラウザ

  • Chrome: 129。
  • Edge: 129。
  • Firefox: 119.
  • Safari: サポートされていません。

ソース

  ...
  const cred = await navigator.credentials.get({
    publicKey: options
  });

  // Encode the credential to JSON and stringify
  const credential = JSON.stringify(cred.toJSON());

  // Send the encoded credential to the server
  await fetch(`/auth/signinResponse`, credential);
  ...

その他の情報

WebAuthn とパスキーについて詳しくは、次のリソースをご覧ください。