このページは自動翻訳されています。英語の原文は こちら.

Passkeysチートシート. パスキープログラム向けの実践ガイド、展開パターン、KPI。
isConditionalMediationAvailable()**を呼び出す必要があります。autocomplete="username webauthn"**トークンは、自動入力ドロップダウンでパスワードの提案と並んでパスキーを表示するようにブラウザに指示します。navigator.credentials.get() 呼び出しで**mediation: "conditional"**を設定すると、ブロックするモーダルダイアログでユーザーを妨げることなくパスキーの自動入力が有効になります。AbortController**が必要です。パスキー(および基盤となるWebAuthnプロトコル)の急速な普及により、認証は多くのユーザーにとってより安全で使いやすいものになりました。パスキーの顕著な進歩の1つは、多くの場合「パスキーの自動入力」またはConditional Mediationと呼ばれるConditional UIの統合です(以下ではConditional UIという用語を使用します)。
ブラウザへの導入や採用が進んでいるにもかかわらず、Conditional UIに関する技術文書や実装に関するアドバイスには明らかなギャップがあります。本記事は、Conditional UIの概要、仕組み、および実装中の一般的な課題への対処方法を解説することで、そのギャップを埋めることを目的としています。
Conditional UIは、パスキー / WebAuthnのログインプロセスにおける新しいモードです。ユーザーがデバイス(例:ラップトップ、スマートフォン)のオーセンティケーターに保存されているリライングパーティ(オンラインサービス)に登録されたdiscoverable credential(resident key、パスキーの一種)を持っている場合にのみ、ユーザーインターフェース(UI)にパスキーを選択的に表示します。パスキーは自動入力されたパスワードと混在する選択ドロップダウンに表示され、ユーザーは同じコンテキストで両方を見ることができるため、従来のパスワードシステムと高度なパスキー認証間のシームレスな移行を提供します。このインテリジェントなアプローチにより、ユーザーは不要なオプションに圧倒されることなく、よりスムーズにログインプロセスを進めることができます。
Igor Gjorgjioski
Head of Digital Channels & Platform Enablement, VicRoads
We hit 80% mobile passkey activation across 5M+ users without replacing our IDP.
See how VicRoads scaled passkeys to 5M+ users — alongside their existing IDP.
Read the case studyConditional UIの基盤は、主に3つの柱の上に構築されています:
最新ニュースを受け取るためにPasskeys Substackを購読しましょう。
以下では、Conditional UIフロー全体の各ステップを段階的に説明します。
一般に、Conditional UIのプロセスフローは2つのフェーズに分けることができます。ページ読み込みフェーズでは、Conditional UIロジックがバックグラウンドで実行されます。一方、ユーザー操作フェーズでは、ユーザーが能動的に何かを行う必要があります。
isConditionalMediationAvailable()関数を呼び出します。応答がtrueの場合のみプロセスが続行され、それ以外の場合はConditional UIプロセスが中止されます。mediationプロパティをconditionalに設定してcredentials.get()を呼び出すことで、デバイス上のローカル認証のプロセスが開始されます。このプロセスフローに従うことで、Conditional UIはシームレスでユーザーフレンドリーな認証エクスペリエンスを提供します。
Conditional UIを機能させるには、いくつかの一般的な側面を考慮する必要があります:
最新情報とサポートのためにPasskeys Communityに参加しましょう。
クライアント側でConditional UIを機能させるには、以下の要件を満たす必要があります:
isConditionalMediationAvailable()メソッドを使用して、Conditional UIの技術的な可用性を確認することをお勧めします(詳細については後述)。Conditional UIを機能させるには、サーバー側でもいくつかの要件を満たす必要があります:
2022年後半のConditional UIの正式なロールアウトとそれ以前のベータ版以降、私たちはこれをテストし、広範に作業してきました。以下では、Conditional UIの実装時に役立った実践的なヒントを共有したいと思います。
Passkeys Debuggerでパスキーフローを試せます。
Conditional UIメソッドの完全で最小限のコード例は次のようになります:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Conditional UI</title> </head> <body> <input type="text" id="username" autocomplete="username webauthn" /> <script> async function passkeyLogin() { try { // WebAuthnサーバーからリクエストオプション(チャレンジを含む)を取得します let options = await WebAuthnClient.getPublicKeyRequestOptions(); const credential = await navigator.credentials.get({ publicKey: options.publicKeyCredentialRequestOptions, mediation: "conditional", }); const userData = await WebAuthnClient.sendSignedChallenge(credential); window.location.href = "/logged-in"; } catch (error) { console.log(error); } } passkeyLogin(); </script> </body> </html>
現在のデバイス / ブラウザの組み合わせがサポートしている場合にのみConditional UIが使用されるように、Conditional UIの検出を実装します。これは、Conditional UIがサポートされていない場合にユーザーにエラーを表示することなく機能する必要があります。ユーザーインターフェース内にisConditionalMediationAvailable()メソッドを組み込むことで、この懸念に対処できます。Conditional UIのサポートが確認されたら、Conditional UIのログインプロセスを開始できます。
// source: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential/isConditionalMediationAvailable#examples // `window.PublicKeyCredential`の可用性は、WebAuthnが使用可能であることを意味します。 if (window.PublicKeyCredential && PublicKeyCredential.isConditionalMediationAvailable) { // conditional mediationが利用可能か確認します。 const isCMA = await PublicKeyCredential.isConditionalMediationAvailable(); if (isCMA) { // WebAuthnの認証開始エンドポイントを呼び出します let options = await WebAuthnClient.getPublicKeyRequestOptions(); const credential = await navigator.credentials.get({ publicKey: options.publicKeyCredentialRequestOptions, mediation: "conditional", }); /* ... */ } }
入力フィールドは、webauthnのHTML自動入力トークンを受け取る必要があります。これにより、進行中のリクエストにパスキーを入力するようにクライアントに合図します。パスキー以外にも、他の自動入力値が表示される場合があります。これらの自動入力トークンは、既存の他のトークンと組み合わせることができます(例:
autocomplete="username webauthn": パスキーの表示に加えて、ユーザー名の自動入力も提案します。autocomplete="current-password webauthn": パスキーの表示に加えて、さらにパスワードの自動入力を促します。<label for="name">Username:</label> <input type="text" name="name" autocomplete="username webauthn" /> <label for="password">Password:</label> <input type="password" name="password" autocomplete="current-password webauthn" />
詳細については、パスキーとパスワードの自動入力 / オートコンプリートトークンの詳細を説明しているブログ記事を読むことをお勧めします。
PublicKeyCredentialRequestOptionsオブジェクトを受信した後に利用可能なパスキーを取得するには、navigator.credentials.get()関数を呼び出す必要があります(これはパスキーとパスワードの両方を提供します)。クライアントでConditional UIを有効にするには、PublicKeyCredentialRequestOptionsオブジェクトのmediationパラメーターをconditionalに設定する必要があります。代わりにモーダルのパスキープロンプトが必要な場合は、immediate mediationを参照してください。
const credential = await navigator.credentials.get({ publicKey: options.publicKeyCredentialRequestOptions, mediation: "conditional", });
利用可能なパスキーがない場合、またはユーザーが提案されたパスキーを無視してメールアドレスを入力した場合、Conditional UIフローは停止します。これは、常にモーダルを介した標準のパスキー / WebAuthnのログインもサポートすることの重要性を強調しています。
ここで強調すべき重要な点は、進行中のConditional UIリクエストを停止する必要がある可能性があることです。モーダルのエクスペリエンスとは対照的に、自動入力ドロップダウンにはキャンセルボタンがありません。WebAuthnの設計に従い、常に単一のアクティブなクレデンシャルリクエストのみが進行中でなければなりません。WebAuthnの標準では、WebAuthnプロセスをキャンセルするためにAbortControllerを利用することを提案しており、これは通常のログインプロセスとConditional UIのログインプロセスの両方に適用できます(詳細についてはこちらを参照してください)。
本番環境のテレメトリでは、このキャンセルパスは多くの場合、予期される制御フローの結果であり、システムの障害ではありません。大量のエラーが発生した場合は、回帰として扱う前に、操作タイプとタイミングによって予期されるケースと予期されないケースを分類する必要があります(WebAuthnエラーを参照)。
ユーザーがページにアクセスするとすぐに、Conditional UIのログインプロセスがアクティブになります。最初のタスクは、グローバルスコープのAbortControllerオブジェクトを作成することです。これは、特にユーザーが通常のパスキーのログインプロセスを実行することを選択した場合に、自動入力リクエストを終了するためのクライアントへのシグナルとして機能します。
AbortControllerが他の関数から呼び出し可能であり、Conditional UIプロセスを再起動する必要がある場合はリセットされることを確認してください。navigator.credentials.get()呼び出し内のsignalプロパティを使用し、値としてAbortControllerのシグナルを組み込みます。これは、シグナルが中止された場合にリクエストを停止する必要があることをパスキー / WebAuthn関数に合図します。Conditional UIをトリガーするたびに、新しいAbortControllerを設定することを忘れないでください。すでに中止されたAbortControllerを使用すると、パスキー / WebAuthn関数が即座にキャンセルされます。残りの手順は、通常のパスキーのログインプロセスと同じです。以下に、説明した手順のコード例を示します:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Conditional UI</title> </head> <body> <input type="text" id="username" autocomplete="username webauthn" /> <script> async function passkeyLogin() { try { // WebAuthnサーバーからリクエストオプション(チャレンジを含む)を取得します let options = await WebAuthnClient.getPublicKeyRequestOptions(); const credential = await navigator.credentials.get({ publicKey: options.publicKeyCredentialRequestOptions, mediation: "conditional", }); const userData = await WebAuthnClient.sendSignedChallenge(credential); window.location.href = "/logged-in"; } catch (error) { console.log(error); } } passkeyLogin(); </script> </body> </html>
Conditional UIがサポートされていない場合は、ユーザーを通常のパスキーログインプロセスに誘導します。このパスを提供することは、ハードウェアセキュリティキー(YubiKeyなど)に依存しているユーザーや、オーセンティケーターの制約によりnon-resident keys / non-discoverable credentialsを使用せざるを得ないユーザーにとって重要です。
実際にどれだけの人がパスキーを使っているか確認できます。
iOSやAndroidなどのネイティブアプリを開発する場合、Conditional UIも機能します。Flutter、Kotlin、Swiftでネイティブに実装するか、Chrome Custom Tabs(CCT)、SFSafariViewController、SFAuthenticationSession / ASWebAuthenticationSessionのいずれを使用するかは関係ありません。どちらのアプローチもConditional UIをサポートしています。
一般的に、iOSアプリにConditional UIサポートを実装する方法に関するドキュメントはほとんど見つかりませんでした。しかし、私たちの調査の過程で、iOSアプリにConditional UIサポートを追加する2つの方法を発見しました。ユーザーエクスペリエンスも異なります。
タイプA: 画面のほぼ全体を覆うオーバーレイ / ポップアップ
最初のタイプAは、画面のほぼ全体に広がるオーバーレイ / ポップアップを表示します。ここでは、このリライングパーティで利用可能なすべてのパスキーが表示されます。この方法でConditional UIを実装している著名な例はKAYAKです。ユーザーが適切な画面を開くと、オーバーレイ / ポップアップが自動的に表示されます。
タイプB: キーボードの自動入力
2番目のタイプBは、キーボードの自動入力セクション(パスワードの自動入力も提案される場所)に適切なパスキーを表示します。提案された値をクリックするとFace ID認証が実行され、ログインできます。Corbadoの開発者パネルの現在のiOSアプリバージョンでは、このように実装しています(WebAuthnのユーザー名と共に、「<relying party ID>のパスキーでサインイン」のメッセージを参照してください)。表示するには、ユーザーが入力フィールドをタップする必要があります:
キーボードセクションのこのパスキー自動入力機能は、iOSが新規インストールされた場合に問題が発生する可能性があります。背景では、このリライングパーティのすべての利用可能なパスキーを検索する一種のキャッシングが行われているようです。
提案されたパスキーの右側にある鍵のアイコンをクリックすると、iOSでパスワード / パスキーを選択するための既知のサイトに移動します:
公式のドキュメントは見つかっておらず、私たちの洞察は適切な実装の具体的な証拠ではなく、私たちの経験と仮説に基づいていることに注意してください。
Androidでは、Android Credential Manager APIを活用するConditional UI / パスキー自動入力のタイプが1つしかないため、Conditional UIについての話は少し明確です(ドキュメントはこちらを参照してください)。Androidプロバイダーは異なる場合があるため、Credential Managerのパスキーエラーは、ブラウザのみのWebAuthnの障害パターンとは別に監視してください。
Conditional UIが実装されているページを開くと次の画面が表示され、サインインするためのさまざまな方法を見つけることができます:
**「保存した他のサインイン情報」**をクリックすると、サインインに選択できるその他のオプションが提供されます(これには、クロスデバイス認証や、Samsung Passや1Passwordなどの異なるパスキー同期プラットフォームの選択が含まれます):
エンドユーザーに対してConditional UIがどのように見えるかを説明するために、https://passkeys.euを使用したConditional UIの自動入力メニューのスクリーンショットをいくつか追加しました。
ライブデモでパスキーを試せます。
実際のアプリケーションにおけるいくつかの一般的なシナリオを見てみましょう。
サイトにパスキーが保存されていない場合、Conditional UIはブラウザやOSによって異なる動作をします。
macOSのChromeでは、入力フィールドをクリックすると空の自動入力ドロップダウンが表示されます:
macOSのSafariでは、ドロップダウンは表示されず、入力フィールドに控えめなアイコンのみが表示されます:
AndroidまたはiOSでは、ユーザーがフィールドをタップし、OSが一致するクレデンシャルを見つけた場合にのみ自動入力インターフェースが表示されます。
このばらつきは意図的なものであり、WebAuthnのプライバシーモデルの一部です。ユーザーが能動的にパスキーを選択しない限り、Webサイトはユーザーがパスキーを持っているかどうかを検出できません。
ユーザーが複数のパスキープロバイダー(iCloudキーチェーン、Googleパスワードマネージャー、1Passwordなど)をインストールしている場合、ブラウザまたはOSは通常、ユーザーのメインのクレデンシャルマネージャーをデフォルトとします。
パスキーをサポートするさまざまなパスキープロバイダー / クレデンシャルマネージャーのリストについては、以下のGitHubリンクを参照することをお勧めします。
Androidでは、Credential ManagerがSamsung Passや1Passwordなどの異なるプロバイダーを公開します。
iOSでは、鍵のアイコンからさまざまなソースのパスキーの完全なリストが開きます。
アプリやWebサイトとして、どのクレデンシャルマネージャーを使用するかを制御することはできません。OSがユーザーのプライバシーを保護するためにその選択を管理します。
Conditional UI / パスキーの自動入力機能を備えたパスキーは、オンラインで認証する新しい方法です。パスワードがますますパスキーに置き換えられる時代に移行するにつれて、堅牢でユーザーフレンドリーな移行メカニズムの必要性は否定できません。本記事は、移行プロセスで非常に役立つConditional UIを正しく実装する方法や、特に注意すべき側面を理解するのに役立ちます。
Corbadoは、大規模なconsumer認証を運用するCIAMチームのためのAuthentication Intelligence Platformです。IDPのログや一般的なanalyticsツールでは見えないものを可視化します。どのデバイス、OSバージョン、ブラウザ、credential managerがpasskeyに対応しているか、なぜ登録がログインにつながらないのか、WebAuthnフローのどこで失敗するか、OSやブラウザのアップデートがいつ静かにログインを壊すか — Okta、Auth0、Ping、Cognito、あるいは自社IDPを置き換えることなく、すべてを把握できます。2つのプロダクト:Corbado Observeは passkeyとその他あらゆるログイン方式のobservabilityを提供します。Corbado Connectは analytics内蔵のmanaged passkeyを追加します(既存のIDPと併用)。VicRoadsはCorbadoで500万人超のユーザーにpasskeyを提供しています(passkey有効化率+80%)。 Passkeyエキスパートに相談する →
PublicKeyCredential.isConditionalMediationAvailable() を呼び出し、trueが返された場合のみ処理を進めます。この確認により、サポートされていないブラウザやデバイスの組み合わせでユーザーにエラーが表示されるのを防ぎます。このメソッドは、mediation: "conditional" を指定して navigator.credentials.get() を呼び出す前の各ページ読み込み時に評価する必要があります。
オーセンティケーターは、resident keys(discoverable credentials)に対してのみ名前や表示名などのユーザー固有のデータを保存します。non-resident keysはこの情報を保持しないため、自動入力メニューにユーザーが選択するためのアカウント詳細を表示することができません。
プラットフォームによって動作が異なります。macOSのChromeでは空の自動入力ドロップダウンが表示され、macOSのSafariでは入力フィールドに控えめなアイコンのみが表示されます。AndroidやiOSでは、ユーザーがフィールドをタップした後にOSが一致するクレデンシャルを見つけた場合にのみ自動入力インターフェースが表示されます。このばらつきは意図的なものであり、WebAuthnのプライバシーモデルの一部です。ユーザーが能動的にパスキーを選択しない限り、Webサイトはパスキーが存在するかどうかを検出できません。
グローバルスコープの AbortController を作成し、そのシグナルを navigator.credentials.get() に渡します。ユーザーがモーダルログインフローを開始したときに、コントローラーで .abort() を呼び出します。すでに中止されたコントローラーを再利用するとWebAuthnリクエストが即座にキャンセルされてしまうため、Conditional UIが再開するたびに常に新しい AbortController をインスタンス化してください。
Conditional UIはネイティブのiOSおよびAndroidアプリの両方で機能します。iOSは、フルスクリーンのオーバーレイポップアップとキーボードの自動入力提案の2つのバリアントをサポートしています。AndroidはCredential Manager APIを使用し、Samsung Passや1Passwordなどの複数のプロバイダーからのパスキーを表示できます。
関連記事
目次