パスキーなどの FIDO 認証情報はパスワードの代替を目的としていますが、そのほとんどはユーザー名を入力する手間も省くことができます。これにより、ユーザーは現在のウェブサイトに登録されているパスキーのリストからアカウントを選択して認証できるようになります。
以前のバージョンのセキュリティ キーは 2 段階認証方式として設計されており、潜在的な認証情報の ID が必要だったため、ユーザー名の入力が必要でした。セキュリティ キーが ID を知らなくても検出できる認証情報は、検出可能な認証情報と呼ばれます。現在作成されている FIDO 認証情報のほとんどは、検出可能な認証情報です。特に、パスワード マネージャーや最新のセキュリティ キーに保存されているパスキーは、検出可能な認証情報です。
認証情報がパスキー(検出可能な認証情報)として作成されるようにするには、認証情報の作成時に residentKey と requireResidentKey を指定します。
証明書利用者(RP)は、パスキー認証中に allowCredentials を省略することで、検出可能な認証情報を使用できます。このような場合、ブラウザまたはシステムは、作成時に設定された user.name プロパティで識別される、利用可能なパスキーのリストをユーザーに表示します。ユーザーが 1 つ選択すると、結果の署名に user.id 値が含まれます。サーバーは、入力されたユーザー名の代わりに、その認証情報 ID または返された認証情報 ID を使用してアカウントを検索できます。
前述のようなアカウント セレクタ UI には、検出不可能な認証情報は表示されません。
requireResidentKey、residentKey
パスキーを作成するには、navigator.credentials.create() で authenticatorSelection.residentKey と authenticatorSelection.requireResidentKey を指定し、次のように値を指定します。
async function register () {
// ...
const publicKeyCredentialCreationOptions = {
// ...
authenticatorSelection: {
authenticatorAttachment: 'platform',
residentKey: 'required',
requireResidentKey: true,
}
};
const credential = await navigator.credentials.create({
publicKey: publicKeyCredentialCreationOptions
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
residentKey:
'required': 検出可能な認証情報を作成する必要があります。作成できない場合は、NotSupportedErrorが返されます。'preferred': RP は検出可能な認証情報の作成を優先しますが、検出不可能な認証情報も受け入れます。'discouraged': RP は検出不可能な認証情報の作成を優先しますが、検出可能な認証情報も受け入れます。
requireResidentKey:
- このプロパティは、仕様の古いバージョンである WebAuthn レベル 1 との下位互換性を維持するために保持されています。
residentKeyが'required'の場合はtrueに設定し、それ以外の場合はfalseに設定します。
allowCredentials
RP は、navigator.credentials.get() で allowCredentials を使用して、パスキー認証エクスペリエンスを制御できます。通常、パスキー認証のエクスペリエンスには次の 3 種類があります。
モーダル アカウント セレクタを表示する
検出可能な認証情報を使用すると、RP はモーダル アカウント セレクタを表示して、ユーザーがログインに使用するアカウントを選択し、ユーザー確認を行うことができます。これは、パスキー認証専用のボタンを押すことで開始されるパスキー認証フローに適しています。
このユーザー エクスペリエンスを実現するには、navigator.credentials.get() の allowCredentials パラメータを省略するか、空の配列を渡します。
async function authenticate() {
// ...
const publicKeyCredentialRequestOptions = {
// Server generated challenge:
challenge: ****,
// The same RP ID as used during registration:
rpId: 'example.com',
// You can omit `allowCredentials` as well:
allowCredentials: []
};
const credential = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
パスキー フォームの自動入力を表示する
上記のモーダル アカウント セレクタは、ほとんどのユーザーがパスキーを使用し、ローカル デバイスでパスキーを利用できる場合に適しています。ローカル パスキーがないユーザーの場合も、モーダル ダイアログが表示され、別のデバイスのパスキーを提示するよう求められます。ユーザーをパスキーに移行する際、パスキーを設定していないユーザーには、この UI を表示しないようにすることをおすすめします。
代わりに、従来のログイン フォームのフィールドの自動入力プロンプトに、保存済みのユーザー名とパスワードとともに、パスキーの選択が組み込まれることがあります。これにより、パスキーを使用しているユーザーはパスキーを選択してログイン フォームに「入力」でき、保存済みのユーザー名とパスワードの組み合わせを使用しているユーザーはそれらを選択でき、どちらも使用していないユーザーはユーザー名とパスワードを入力できます。
このユーザー エクスペリエンスは、RP がパスワードとパスキーを併用して移行している場合に最適です。
このユーザー エクスペリエンスを実現するには、allowCredentials プロパティに空の配列を渡すか、パラメータを省略することに加えて、navigator.credentials.get() で mediation: 'conditional' を指定し、HTML username 入力フィールドに autocomplete="username webauthn" のアノテーションを付けるか、password 入力フィールドに autocomplete="password webauthn" のアノテーションを付けます。
navigator.credentials.get() を呼び出しても UI は表示されませんが、ユーザーがアノテーション付きの入力フィールドにフォーカスすると、利用可能なパスキーが自動入力オプションに含まれます。ユーザーが 1 つ選択すると、通常のデバイスロック解除の確認が行われ、その後、.get() から返された Promise が結果とともに解決されます。ユーザーがパスキーを選択しない場合、Promise は解決されません。
async function authenticate() {
// ...
const publicKeyCredentialRequestOptions = {
// Server generated challenge:
challenge: ****,
// The same RP ID as used during registration:
rpId: 'example.com',
// You can omit `allowCredentials` as well:
allowCredentials: []
};
const cred = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal,
// Specify 'conditional' to activate conditional UI
mediation: 'conditional'
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
<input type="text" name="username" autocomplete=&qu>ot;username webauthn" ...
このユーザー エクスペリエンスを構築する方法については、フォームの自動入力でパスキーを使用してログインすると、ウェブアプリでフォームの自動入力を使用してパスキーを実装する Codelab をご覧ください。
再認証
再認証にパスキーを使用する場合など、ユーザーの識別子がすでにわかっている場合があります。この場合、ブラウザや OS にアカウント選択ツールを表示せずにパスキーを使用します。これは、allowCredentials パラメータに認証情報 ID のリストを渡すことで実現できます。
この場合、名前付き認証情報のいずれかがローカルで使用可能であれば、ユーザーはすぐにデバイスのロック解除を求められます。そうでない場合、ユーザーは有効な認証情報を保持する別のデバイス(スマートフォンまたはセキュリティ キー)を提示するよう求められます。
このユーザー エクスペリエンスを実現するには、ログインするユーザーの認証情報 ID のリストを指定します。ユーザーはすでに認識されているため、RP はユーザーをクエリできる必要があります。navigator.credentials.get() の allowCredentials プロパティに PublicKeyCredentialDescriptor オブジェクトとして認証情報 ID を指定します。
async function authenticate() {
// ...
const publicKeyCredentialRequestOptions = {
// Server generated challenge:
challenge: ****,
// The same RP ID as used during registration:
rpId: 'example.com',
// Provide a list of PublicKeyCredentialDescriptors:
allowCredentials: [{
id: ****,
type: 'public-key',
transports: [
'internal',
'hybrid'
]
}, {
id: ****,
type: 'public-key',
transports: [
'internal',
'hybrid'
]
}, ...]
};
const credential = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
signal: abortController.signal
});
// This does not run until the user selects a passkey.
const credential = {};
credential.id = cred.id;
credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
credential.type = cred.type;
// ...
}
PublicKeyCredentialDescriptor オブジェクトは、次の要素で構成されます。
id: RP がパスキー登録時に取得した公開鍵認証情報の ID。type: このフィールドは通常'public-key'です。transports: この認証情報を保持するデバイスでサポートされているトランスポートのヒント。ブラウザが、外部デバイスの提示をユーザーに求める UI を最適化するために使用します。このリストを指定する場合、各認証情報の登録時にgetTransports()を呼び出した結果が含まれている必要があります。
概要
検出可能な認証情報を使用すると、ユーザー名を入力する必要がなくなるため、パスキーによるログイン エクスペリエンスが大幅に向上します。residentKey、requireResidentKey、allowCredentials を組み合わせることで、RP は次のようなログイン エクスペリエンスを実現できます。
- モーダル アカウント セレクタを表示します。
- パスキー フォームの自動入力を表示する。
- 再認証。
検出可能な認証情報を適切に使用します。これにより、ユーザーがシームレスに利用でき、エンゲージメントを高めることができる、洗練されたパスキー ログイン エクスペリエンスを設計できます。