コンテンツにスキップ

Passkey認証

概要

Passkeyは生体認証(指紋、顔認識)やセキュリティキーを使ったパスワードレス認証です。SDKの auth.passkey 名前空間はWebAuthn APIをラップし、クレデンシャルの作成、アサーション、サーバー側の検証を処理します。

Passkeyとは

PasskeyはFIDO2/WebAuthnクレデンシャルで、ユーザーのデバイスまたはプラットフォーム認証器(iCloudキーチェーン、Googleパスワードマネージャー、Windows Hello)に保存されます:

  • フィッシング耐性 — クレデンシャルはオリジン(ドメイン)にバインド
  • パスワード不要 — 生体認証またはPINで認証
  • デバイス間で同期 — プラットフォーム認証器がクラウド経由でパスキーを同期

サポート確認

PasskeyのUIを表示する前に、ブラウザのWebAuthnサポートを確認します:

// 同期チェック
if (auth.passkey.isSupported()) {
// Passkeyログインボタンを表示
}
// Conditional UI(オートフィル)が利用可能か確認
const hasConditionalUI = await auth.passkey.isConditionalUIAvailable();

サインアップ

Passkeyで新しいアカウントを作成します。ユーザー作成とWebAuthnクレデンシャル登録を1ステップで行います:

const { data, error } = await auth.passkey.signUp({
});
if (error) {
console.error('サインアップ失敗:', error.message);
return;
}
console.log('アカウント作成完了:', data.user);
console.log('セッション:', data.session);

サインアップオプション

interface PasskeySignUpOptions {
/** ユーザーのメールアドレス(必須) */
email: string;
/** 表示名(オプション) */
displayName?: string;
}

内部動作

  1. SDKがAuthrimサーバーに登録リクエストを送信
  2. サーバーがWebAuthn作成オプション(チャレンジ、リライングパーティ情報)を返す
  3. ブラウザが生体認証を要求
  4. ブラウザが公開鍵クレデンシャルを作成
  5. SDKがクレデンシャルをサーバーに送信
  6. サーバーがユーザーアカウントを作成、クレデンシャルを保存、セッションを返す

サインイン

既存ユーザーをPasskeyで認証します:

const { data, error } = await auth.passkey.login();
if (error) {
console.error('ログイン失敗:', error.message);
return;
}
console.log('おかえりなさい:', data.user);

メールやユーザー名は不要です — ブラウザが現在のオリジンで利用可能なパスキーを提示します。

ログインオプション

interface PasskeyLoginOptions {
/** 推奨する認証器の接続方式 */
authenticatorAttachment?: 'platform' | 'cross-platform';
/** Conditional UI(オートフィル)を使用するか */
conditionalUI?: boolean;
}

Conditional UI(オートフィル)

Conditional UIはPasskeyの選択をブラウザのオートフィルメニューに統合します。専用の「Passkeyでサインイン」ボタンの代わりに、保存されたパスワードと同じオートフィルドロップダウンにパスキーが表示されます:

// 利用可能か確認
if (await auth.passkey.isConditionalUIAvailable()) {
// Conditional UIを開始(非ブロッキング)
auth.passkey.login({ conditionalUI: true })
.then(({ data, error }) => {
if (data) {
console.log('オートフィルでサインイン:', data.user);
}
});
}

保留中のConditional UIリクエストをキャンセルするには(例:ページ遷移時):

auth.passkey.cancelConditionalUI();

追加Passkeyの登録

既存アカウントに新しいパスキーを追加します。ユーザーは既に認証済みである必要があります:

const { data, error } = await auth.passkey.register();
if (error) {
console.error('登録失敗:', error.message);
return;
}
console.log('新しいパスキーを登録しました:', data);
// data: PasskeyCredential { id, publicKey, ... }

これは以下の場合に有用です:

  • バックアップとしてセキュリティキーを追加
  • 新しいデバイスでパスキーを登録
  • 設定/プロフィールページの「パスキーを追加」機能

登録オプション

interface PasskeyRegisterOptions {
/** 推奨する認証器の接続方式 */
authenticatorAttachment?: 'platform' | 'cross-platform';
}

エラーハンドリング

よくあるPasskeyエラー:

エラーコード意味ユーザーへのアクション
AR003001WebAuthn非対応代替ログイン方法を表示
AR003002ユーザーがセレモニーをキャンセルリトライまたは代替手段を提供
AR003003クレデンシャルが見つからないサインアップまたは別の方法を提案
AR003004認証器エラーリトライまたはサポートへ連絡
AR003005サーバー検証失敗操作をリトライ
const { data, error } = await auth.passkey.login();
if (error) {
switch (error.code) {
case 'AR003002':
// ユーザーがキャンセル — 何もしないか控えめなメッセージ
break;
case 'AR003003':
// クレデンシャルなし — サインアップを提案
showMessage('パスキーが見つかりません。サインアップしますか?');
break;
default:
showMessage(error.message);
}
}

完全な例

import { createAuthrim } from '@authrim/web';
const auth = await createAuthrim({
issuer: 'https://auth.example.com',
clientId: 'my-app',
});
// サポート確認
if (!auth.passkey.isSupported()) {
document.getElementById('passkey-section').style.display = 'none';
}
// サインインボタン
document.getElementById('passkey-login').addEventListener('click', async () => {
const { data, error } = await auth.passkey.login();
if (error) {
alert(error.message);
return;
}
window.location.href = '/dashboard';
});
// サインアップボタン
document.getElementById('passkey-signup').addEventListener('click', async () => {
const email = document.getElementById('email-input').value;
const { data, error } = await auth.passkey.signUp({ email });
if (error) {
alert(error.message);
return;
}
window.location.href = '/dashboard';
});
// パスキー追加ボタン(プロフィールページ、ユーザーは認証済み)
document.getElementById('add-passkey').addEventListener('click', async () => {
const { data, error } = await auth.passkey.register();
if (error) {
alert(error.message);
return;
}
alert('パスキーを追加しました');
});

次のステップ