ユーザーがパスキーをよりシームレスに導入できるようにする

公開日: 2025 年 5 月 9 日、最終更新日: 2025 年 12 月 22 日

パスキーは、フィッシング対策に有効な強固な認証を提供します。ただし、ユーザーにこれらの機能を採用してもらうには、摩擦が生じる可能性があります。パスキーの自動作成を使用すると、ユーザーがサイトのパスワードをすでに保存している場合に、適切なタイミングでユーザーのパスキーを作成できます。条件付き作成(パスキーの自動作成を可能にする)は、WebAuthn 仕様の一部です。

仕組み

ユーザーがより便利にパスキーを採用できるようにするには、条件付き作成と呼ばれる WebAuthn API 機能を使用します。条件付き作成を使用すると、サイトはユーザーの操作を必要とせずに、ユーザーのパスキーをリクエストできます。

このフローは、次の条件を満たす場合に機能します。

  • ユーザーがデフォルトのパスワード マネージャーにパスワードを保存している。
  • パスワードが最近使用された。理想的には、パスワード ベースのログインが成功した直後に Conditional Create を呼び出します。

両方の条件が満たされている場合は、条件付き作成を呼び出して、パスワード マネージャーにユーザーのパスキーの作成をリクエストできます。パスキーの作成に成功すると、パスワード マネージャーに応じてユーザーに通知されます。

条件付き作成を含むパスキー リクエスト フロー。

互換性

条件付き作成は、macOS の Safari と iOS のすべてのブラウザデスクトップの ChromeAndroid の Chrome でサポートされています。

つまり、macOS と iOS の Safari の iCloud キーチェーン(パスワード)、パソコンと Android の Chrome の Google パスワード マネージャーという、それぞれのデフォルトのパスキー プロバイダで動作します。

iOS 18 以降と Android 14 以降ではサードパーティのパスキー プロバイダがサポートされているため、ユーザーが使用するブラウザに関係なく、条件付き作成のサポートはパスキー プロバイダ次第となります。選択したパスキー プロバイダが条件付き作成をサポートしていない場合、新しいパスキーは作成されません。

条件付き作成を実装する

パスキーの自動作成は、条件付き作成と呼ばれる WebAuthn API 機能に基づいています。これらは、mediation パラメータが "conditional" に設定された通常の WebAuthn create() リクエストです。これは、get() リクエストのパスキーの自動入力と同様に機能します。

ユーザーがパスワードでログインした後に、条件付き作成を使用します。作成が成功するかどうかは、パスワード マネージャーと特定の条件が満たされているかどうかによって異なります。これらの条件はパスワード マネージャーによって異なり、時間の経過とともに変更される可能性があります。たとえば、Google パスワード マネージャー(GPM)を使用する Chrome では、ユーザーがサイトの保存済みパスワードを使用して最近ログインしている必要があります。

ブラウザがパスキーを正常に作成すると、公開鍵認証情報が返されます。この認証情報をバックエンドに送信して、登録を完了し、今後の認証を有効にします。

特徴検出

PublicKeyCredential.getClientCapabilities() を呼び出すことで、ブラウザで Conditional Create が利用可能かどうかを判断できます。返されたオブジェクトに conditionalCreate プロパティの true が含まれているかどうかを確認します。

if (window.PublicKeyCredential && PublicKeyCredential.getClientCapabilities) {
  const capabilities = await PublicKeyCredential.getClientCapabilities();
  if (capabilities.conditionalCreate) {
    // Conditional create is available
  }
}

getClientCapabilities が使用できない場合、条件付き作成も使用できません。

条件付きでパスキーを作成する

パスキーの自動作成を行うには、次のように mediation: "conditional" を指定して navigator.credentials.create() を呼び出します。

const cred = await navigator.credentials.create({
  publicKey: options,
  // Request conditional creation
  mediation: 'conditional'
});

自動作成のパスワード マネージャーの条件を満たす可能性を最大限に高めるには、ユーザーがログインした直後にパスキーの自動作成を使用する必要があります。

生成された公開鍵認証情報をサーバーに送信して、パスキーを検証して登録できます。サーバーで、ユーザーがログインしていることを確認します。

注意点

条件付き作成自体は実装が難しいものではありませんが、この機能を既存のシステムに実際に統合する際にはいくつかの注意点があります。

サーバーでユーザーの存在とユーザー確認を無視する

登録レスポンスは「User Presence」と「User Verified」の両方を false として返すため、サーバーは認証情報の検証時にこれらのフラグを無視する必要があります

パスキーの自動作成を行う前に進行中の WebAuthn 呼び出しを中止

RP がパスキーまたはパスワードのいずれかでユーザーがログインすることを想定している場合、条件付き取得を行うのが最善の方法です。これにより、条件付き作成を実行する前に条件付き get 呼び出しがキャンセルされることがあります。

そのためには、AbortController を使用して .abort() を呼び出す必要があります。

// To abort a WebAuthn call, instantiate an AbortController.
const controller = new AbortController();

const cred = await navigator.credentials.get({
  publicKey: options,
  signal: controller.signal,
  // Request conditional get
  mediation: 'conditional'
});

// Abort the call
controller.abort();

例外を適切に無視する

条件付きパスキーの作成が実行される場合、例外を無視する必要があるケースがいくつかあります。

  • InvalidStateError: パスキー プロバイダにパスキーがすでに存在します。excludeCredentials を指定してください。
  • NotAllowedError: パスキーの作成が条件を満たしていません。
  • AbortError: WebAuthn 呼び出しが中止されました。

このような場合にエラーを表示すると、ブラウザがエラーをサイレントに処理するため、ユーザーが混乱する可能性があります。ブラウザは成功した場合にのみ通知を表示し、失敗した場合はメッセージを表示しません。

パスキーの登録が失敗したときにシグナルを送信する

パスキーが作成されたもののサーバーに登録できなかった場合、ユーザーはログイン試行の失敗を経験します。これは、パスキー プロバイダとサーバー間でパスキーのリストに不整合がある場合に発生する可能性があります。

このような状況を回避するには、Signal API を使用して一貫性を保ちます

パスワードレス ログインからのアップグレードはサポートされていません

この時点で、パスキーの条件付き作成は、ユーザーが有効なパスワードを入力した後にのみ実行されます。つまり、マジックリンク、電話番号の確認、ID フェデレーションなどのパスワードレス ログイン方法は条件を満たしません。

概要

パスキーの自動作成は、ウェブサイトでのパスキーの導入を促進し、ウェブサイトのユーザーがパスワードからより安全な認証方法に移行するのに役立ちます。

パスキーについて詳しくは、パスキーによるパスワードなしのログインをご覧ください。