パスワードはアカウントセキュリティの最も弱いリンクです。フィッシングされたり、漏洩したり、使い回されたり、忘れられたりする可能性があります。そのため、WebAuthn Passkeysのサポートを追加しました - フィッシング耐性があり、より安全で便利なパスワードレス認証方式です。

Passkeysとは?

Passkeysは、デバイス(スマートフォン、ラップトップ、セキュリティキー)に保存される暗号化された認証情報で、認証時にパスワードを置き換えます。WebAuthn標準(FIDO2の一部)を使用し、いくつかの利点を提供します:

  • フィッシング耐性 - Passkeysはウェブサイトのドメインに紐付けられているため、偽サイトでは使用できません
  • 漏洩するシークレットがない - サーバーには公開鍵のみが保存されます
  • デバイスに紐付け - 秘密鍵はデバイスから離れることはありません
  • 生体認証で保護 - 通常、Face ID、Touch ID、またはWindows Helloで保護されます
  • デバイス間同期 - 最新のプラットフォームはiCloud、Google、またはMicrosoftアカウントを介してデバイス間でPasskeysを同期します

私たちの実装

既存のdjango-allauth認証スタックにWebAuthn Passkeysサポートを統合し、WebとモバイルAPIの両方のエンドポイントを提供しています。

登録フロー

ユーザーが新しいPasskeyを登録する際、フローは次のように動作します:

  1. クライアントが登録オプションをリクエストする
  2. サーバーがチャレンジを生成し、ユーザーとリライングパーティの情報を含める
  3. ブラウザのWebAuthn APIがユーザーにプロンプトを表示(生体認証またはセキュリティキー)
  4. クライアントが認証情報を送信する
  5. サーバーが検証して保存する
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# API endpoint to begin registration
class WebAuthnRegistrationOptionsView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        from allauth.mfa.webauthn.internal import auth as webauthn_auth

        # Generate credential creation options
        creation_options = webauthn_auth.begin_registration(
            request.user,
            passwordless=False  # Use as 2FA, not passwordless
        )

        return Response({
            "success": True,
            "creation_options": creation_options,
        })

認証フロー

Passkeysを使用した二要素認証の場合:

  1. ユーザーがプライマリ認証を完了(ユーザー名/パスワードまたはソーシャルログイン)
  2. サーバーがWebAuthn検証のためのチャレンジを返す
  3. ブラウザがPasskeyを要求(生体認証タッチ)
  4. 認証情報が保存された公開鍵に対して検証される
  5. ユーザーが完全に認証される
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class WebAuthnVerifyView(APIView):
    def post(self, request):
        credential = request.data.get("credential")

        # Complete authentication and verify credential
        authenticator = webauthn_auth.complete_authentication(
            request.user,
            credential
        )

        # Record usage for security monitoring
        authenticator.last_used_at = timezone.now()
        authenticator.save()

        return Response({"success": True})

Passkey管理

ユーザーは登録されたPasskeysを管理できます:

  • すべてのPasskeysを一覧表示 - 登録日と最終使用日を含む
  • Passkeysの名前を変更 - 識別しやすくするため(例:「iPhone」、「MacBook」)
  • Passkeysを削除 - 最後の認証器の削除からの保護付き
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class WebAuthnListView(APIView):
    def get(self, request):
        authenticators = Authenticator.objects.filter(
            user=request.user,
            type=Authenticator.Type.WEBAUTHN
        ).order_by("-created_at")

        return Response({
            "passkeys": [
                {
                    "id": auth.pk,
                    "name": auth.wrap().name,
                    "created_at": auth.created_at.isoformat(),
                    "last_used_at": auth.last_used_at.isoformat() if auth.last_used_at else None,
                }
                for auth in authenticators
            ]
        })

APIエンドポイント

当社のREST APIはモバイルアプリに完全なWebAuthnサポートを提供します:

エンドポイントメソッド説明
/api/webauthn/register/options/GET登録チャレンジを取得
/api/webauthn/register/complete/POST登録を完了
/api/webauthn/authenticate/options/GET認証チャレンジを取得
/api/webauthn/verify/POST2FAの認証情報を検証
/api/webauthn/GET登録済みPasskeysを一覧表示
/api/webauthn/<id>/PATCHPasskeyの名前を変更
/api/webauthn/<id>/DELETEPasskeyを削除

セキュリティに関する考慮事項

リカバリーコード

ユーザーが最初の認証器(PasskeyまたはTOTP)を登録すると、自動的にリカバリーコードを生成します。これらのワンタイムコードは、他のすべての認証方法が利用できなくなった場合に使用できます:

1
2
if Authenticator.objects.filter(user=request.user).count() == 1:
    auto_generate_recovery_codes(request._request)

ロックアウト防止

ユーザーは、二要素認証方法がなくなる場合、最後のPasskeyを削除できません:

1
2
3
4
if not adapter.can_delete_authenticator(authenticator):
    return Response({
        "message": "Cannot delete - you must have at least one authentication method"
    }, status=400)

モニタリング

セキュリティモニタリングのためにDatadogメトリクスを通じてPasskeyの使用状況を追跡しています:

1
2
3
increment("webauthn.registration.success")
increment("webauthn.verify.success")
increment("webauthn.verify.failed")

ブラウザサポート

WebAuthnはすべての最新ブラウザでサポートされています:

  • Chrome 67+
  • Firefox 60+
  • Safari 13+
  • Edge 79+
  • モバイルChrome、Safari、Firefox

古いブラウザでは、ユーザーはTOTP(認証アプリ)またはリカバリーコードを引き続き使用できます。

ユーザーエクスペリエンス

Passkeyの追加は数秒で完了します:

  1. 設定 → セキュリティ → 二要素認証に移動
  2. Passkeyを追加をクリック
  3. デバイスに名前を付ける(例:「iPhone 15」)
  4. Face ID / Touch ID / Windows Helloで認証
  5. 完了!Passkeyが登録されました

今後のログインでは生体認証の確認だけで済みます - パスワードの入力や認証アプリからのコードのコピーは不要です。

Passkeysを選んだ理由

方法フィッシングリスクユーザーエクスペリエンスリカバリー
パスワード悪い(忘れやすい、弱い)メールリセット
SMS 2FA中(SIMスワップ)まあまあ電話番号
TOTPアプリ手動コード入力バックアップキー
Passkeys非常に低い優秀リカバリーコード

Passkeysは認証の未来を代表しています。Apple、Google、Microsoftのプラットフォームですでにサポートされており、ほぼすべてのユーザーがアクセスできます。


パスワードレスに移行する準備はできましたか?セキュリティ設定でPasskeysを有効にしてください!