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'
    }
  }
});
ヒントとして「ハイブリッド」を指定すると、ブラウザにクロスデバイス ログイン フォーカス ダイアログが表示されます。 ヒントとして「ハイブリッド」を指定すると、ブラウザにクロスデバイス ログインにフォーカスしたダイアログが表示されます。

関連オリジン リクエストを使用すると、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 のリクエスト オブジェクトとレスポンス オブジェクトには、ArrayBuffer 内の未加工バイナリ データを含む複数のフィールド(認証情報 ID、ユーザー ID、チャレンジなど)があります。ウェブサイトが 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 とパスキーの詳細については、以下のリソースをご覧ください。