---
url: 'https://www.corbado.com/ja/blog/native-app-passkeys'
title: 'ネイティブアプリでのパスキー: ネイティブとWebView実装の比較'
description: 'iOSやAndroidのネイティブアプリでパスキーを実装する方法を解説します。ネイティブとWebView実装の使い分けや、各種アプローチの利点について学びましょう。'
lang: 'ja'
author: 'Vincent Delitz'
date: '2025-06-20T15:08:47.826Z'
lastModified: '2026-09-16T06:02:40.480Z'
keywords: 'webview, ネイティブアプリ, ネイティブiOSアプリ, ネイティブAndroidアプリ, CCT, Chromeカスタムタブ, wkwebview, sfsafariviewcontroller, sfauthenticationsession, aswebauthenticationsession'
category: 'WebAuthn Know-How'
---

# ネイティブアプリでのパスキー: ネイティブとWebView実装の比較

### ネイティブアプリのパスキー実装: クイックリファレンス

| **アプローチ**      | **採用状況** | **パスキーの作成**                         | **パスキーの使用**                                                            | **パスキーの管理**   | **技術的複雑さ** | **OAuthのサポート** |
| :------------------ | :----------: | :----------------------------------------- | :---------------------------------------------------------------------------- | :------------------- | :--------------- | :------------------ |
| **ネイティブ実装**  |    🟢🟢🟢    | 高い採用率、最高のUX、シームレスな生体認証 | 即座にサイレントな認証                                                        | 完全なネイティブ制御 | 中〜高           | 別途フローが必要    |
| **システムWebView** |     🟢🟢     | 良好な採用率、ブラウザに近い体験           | 標準的なブラウザのUX、共有キーチェーン                                        | ブラウザベースの管理 | 低               | 優れている          |
| **埋め込みWebView** |      🟢      | 採用率は低め、追加の設定が必要             | iOSおよびAndroidのネイティブサポート（WebKit 1.12.1以上）、Conditional UIなし | 限定的な制御         | 中〜高           | 該当なし            |

**注意:**
システム[WebView](https://www.corbado.com/blog/native-app-passkeys)と埋め込み[WebView](https://www.corbado.com/blog/native-app-passkeys)は組み合わせて使用されることが多く、システム[WebView](https://www.corbado.com/blog/native-app-passkeys)でログイン（自動的な認証情報の共有を含む）を処理し、埋め込みWebViewで設定画面のパスキー管理をレンダリングします。

**重要な決定要因:**

- **OAuthベースのログイン？**
  → システムWebView（[ASWebAuthenticationSession](https://www.corbado.com/blog/native-app-passkeys)、[Chrome](https://www.corbado.com/ja/blog/digital-credentials-api)カスタムタブ）
- **ネイティブシェル内でWeb認証を再利用したい？**
  → 埋め込みWebView（[WKWebView](https://www.corbado.com/blog/native-app-passkeys)、WebKit
  1.12.1以上の[Android](https://www.corbado.com/blog/how-to-enable-passkeys-android) WebView）
- **ネイティブファーストのアプリを構築する？**
  → ネイティブ実装（[Apple](https://www.corbado.com/ja/blog/how-to-enable-passkeys-macos)
  AuthenticationServices、Google Credential Manager）

## Key Facts

- **preferImmediatelyAvailableCredentials**
  を使用すると、アプリの起動時に即座に自動的なパスキーオーバーレイが表示されます。これはネイティブ実装専用であり、どのWebViewバリアントでも利用できません。
- **システムWebView**（iOSのASWebAuthenticationSession、AndroidのChromeカスタムタブ）は、OAuthベースのログインに推奨されるアプローチであり、ネイティブコードが最小限で済み、関連付けファイルも不要です。
- **Androidの埋め込みWebView** では、ランタイム機能の検出を備えたAndroidX WebKit
  1.12.1以上が必要です。Conditional
  UI（入力フィールドでのパスキー自動入力）はこのアプローチではサポートされていません。
- **Well-known関連付けファイル**（iOSのAASA、Androidのassetlinks.json）は、ネイティブ実装および埋め込みWebView実装には必要ですが、システムWebViewには不要です。

## 1. ネイティブアプリのパスキー実装の選択肢

最新のモバイルプラットフォームでは、ネイティブアプリにパスキーを統合するための3つの異なるアプローチが提供されており、それぞれユーザー体験、技術的な複雑さ、OAuthの互換性においてトレードオフがあります。

1. **ネイティブ実装**: プラットフォームのAPI（[iOS](https://www.corbado.com/blog/how-to-enable-passkeys-ios)のAuthenticationServices、[Android](https://www.corbado.com/blog/how-to-enable-passkeys-android)のCredential
   Manager）を使用して、アプリのUIに直接パスキーのフローを構築します。シームレスな生体認証による最高のユーザー体験を提供しますが、中〜高程度の技術的な実装作業が必要です。

2. **システムWebView**: プラットフォームのブラウザコンポーネント（**iOSのASWebAuthenticationSession
   /
   SFSafariViewController、AndroidのChromeカスタムタブ**）を使用して認証を処理します。OAuthベースのログインフローに最適であり、システムブラウザと認証情報を共有します。

3. **埋め込みWebView**: カスタマイズ可能なWebView（**iOSのWKWebView、AndroidのWebView**）をアプリ内に埋め込み、ネイティブアプリの骨組みとともにWeb認証を再利用します。URLバーのないネイティブな外観と、WebViewのUIに対する完全な制御を提供します。パスキー機能を有効にするには、権限やエンタイトルメント（[iOS](https://www.corbado.com/blog/how-to-enable-passkeys-ios)）、およびAndroidX
   WebKit
   1.12.1以上のWebView構成（[Android](https://www.corbado.com/blog/how-to-enable-passkeys-android)）などの追加の設定が必要です。

適切な選択は、アプリの認証アーキテクチャ、OAuthプロバイダーを使用しているかどうか、UIをどの程度制御する必要があるか、ネイティブファーストで構築しているか、またはWebコンポーネントを再利用しているかによって異なります。

### 1.1 ネイティブ実装: 最高のユーザー体験

ネイティブのパスキー実装は、プラットフォーム固有のAPIを使用してアプリのUIに直接組み込まれた認証フローにより、最適なユーザー体験を提供します。ユーザーは、プラットフォームネイティブのダイアログ、シームレスな生体認証、および可能な限り最速のログイン時間の恩恵を受けます。

**ネイティブ実装を選択すべきケース:**

- **新しいネイティブアプリを構築するか、認証をネイティブ画面にリファクタリングする**場合
- 即座にサイレントな認証による**可能な限り最高のユーザー体験**を求める場合
- **アプリ起動時の自動パスキープロンプト**: ネイティブ実装では、`preferImmediatelyAvailableCredentials`
  を使用して、パスキーが利用可能な場合に[自動的にパスキーオーバーレイを表示](https://docs.corbado.com/passkey-ui-flows/native/passkey-login/overlay)できます。これにより、識別子を入力することなく、最速のログイン体験が提供されます。
- 認証のUIとフローを完全に制御する必要がある場合
- プラットフォーム固有の実装（[iOS](https://www.corbado.com/blog/how-to-enable-passkeys-ios)のSwift、AndroidのKotlin）に投資する意思がある場合

**主な利点: preferImmediatelyAvailableCredentials()**

ネイティブ実装では `preferImmediatelyAvailableCredentials()`
を活用して、パスキーが利用可能な場合にアプリの起動時に即座に表示される自動パスキーオーバーレイを作成できます。このユーザー名不要のフローは、可能な限り最速のログイン体験を提供します。ユーザーは識別子を先に入力することなく、即座にパスキーを確認できます。この機能は**ネイティブ実装専用**であり、WebViewのバリアントでは利用できません。

以下の図は、ネイティブ認証がWebViewの[Conditional UI](https://www.corbado.com/glossary/conditional-ui)アプローチと比較して、どのように高速なユーザー体験を提供するかを示しています。

ネイティブの自動オーバーレイは、アプリ起動時に即座に認証が開始されるため、WebView実装がユーザーに入力フィールドの操作を求めるのに対し、パスキーの利用率が高く、優れたUXを提供します。

**技術的要件の概要:**

ネイティブのパスキー統合には、アプリとWebドメイン間の暗号化による信頼が必要です。これがないと、OSはすべてのWebAuthn操作を拒否します。主な要件は次のとおりです。

1. `/.well-known/` でホストされる**アプリドメイン関連付けファイル**
2. Webドメインと一致する**正しいRelying Party ID**
3. **プラットフォーム固有の機能**（セクション4で詳述）

最大のメリット:
Webサイトで作成されたパスキーがアプリでシームレスに機能し、その逆も同様です。

#### 1.1.1 iOSでのネイティブパスキー (Swift)

iOSでパスキーをネイティブに実装するには、WebAuthn操作用のAPIを提供する[Apple](https://www.corbado.com/ja/blog/how-to-enable-passkeys-macos)の**AuthenticationServices**フレームワークを使用します。

**主なコンポーネント:**

- `ASAuthorizationController`: 認証フローを管理します
- `ASAuthorizationPlatformPublicKeyCredentialProvider`: パスキー要求を作成します
- パスキーのログインを処理する3つの異なるUIモード:
    - **テキストフィールドログイン**: 従来のユーザー名フィールド。ボタン送信時にパスキーログインが開始されます
    - **パスキーモーダルオーバーレイ**: 利用可能なパスキーをリストするOSのダイアログ
    - **Conditional UI**: キーボードの上のQuickTypeバーにパスキーの提案を表示します

**開発のヒント**

- **AASAのキャッシュ**:
  [Apple](https://www.corbado.com/ja/blog/how-to-enable-passkeys-macos)はAASAファイルを積極的にキャッシュするため（最大24時間）、テストの妨げになる可能性があります。解決策: テストデバイスでデベロッパーモードを有効にし、AASAのURLに
  `?mode=developer` を追加して、強制的に最新のファイルを取得します。
- **パフォーマンステスト**: 実際の遅延を観察するために、数百の認証情報を含むiCloudアカウントでテストします。保存されているパスキーが多いと、システムのオーバーレイにわずかな遅延が生じる場合があります。

#### 1.1.2 Androidでのネイティブパスキー (Kotlin)

Androidのネイティブパスキー実装では、**Credential Manager
API**（または下位互換性のための古い[FIDO2](https://www.corbado.com/glossary/fido2) API）を使用します。

**主なコンポーネント:**

- `CredentialManager`: すべての認証情報操作の中心となるAPI
- `CreatePublicKeyCredentialRequest`: パスキーの登録用
- `GetCredentialRequest`: パスキーの認証用
- 2つの主要なUIモード:
    - **テキストフィールドログイン**: 従来のユーザー名フィールド。ボタン送信時にパスキーログインが開始されます
    - **パスキーモーダルオーバーレイ**: 利用可能なパスキーをリストするOSのダイアログ

注: 現在、Androidのネイティブアプリには、iOSの[Conditional UI](https://www.corbado.com/glossary/conditional-ui)のようなキーボードでの提案機能はありません（ただし、Webアプリでは[Conditional UI](https://www.corbado.com/glossary/conditional-ui)が機能します）。

#### 1.1.3 実装の課題と解決策

パスキーをネイティブに実装するには、重要な課題と学んだ教訓があります。OSレベルで統合すると、デバイスやOSのバージョン間で問題が発生する可能性があります。

1. たとえば、私たちのチームは、[apple-app-site-association](https://www.corbado.com/ja/blog/webauthn-relying-party-id-rpid-passkeys)ファイル（アプリとWebの認証情報をリンクするために使用）のAppleによる積極的なキャッシュや、一部のAndroid
   OEMの生体認証プロンプトにおける微妙なUIの違いなどの問題に直面しました。
2. さらに、一部のエンタープライズシナリオでは、管理対象デバイスのポリシーによりパスキーの同期が無効になっている場合があることを考慮してください。iCloudキーチェーンやGoogleパスワードマネージャーの同期がオフになっている企業環境では、パスキーはデバイスにバインドされ、ローミングされません。これは計画すべき重要なシナリオです（たとえば、ユーザーが新しいスマートフォンを受け取った場合でもログインできるようにするなど）。
3. さらに、サードパーティのクレデンシャルマネージャーアプリがフローに影響を与える可能性があります。たとえば、ユーザーが[1Password](https://www.corbado.com/blog/1password-passkeys-best-practices-analysis)のようなパスワードマネージャーをアクティブなプロバイダーとして設定している場合、多くの場合、パスキーの作成と保存を傍受し、プラットフォームのネイティブなクレデンシャルマネージャーよりも優先されます。

#### 1.1.4 ネイティブSDKによる簡素化

生のプラットフォームAPIを使用してパスキーを実装することもできますが、専用のSDKを使用すると、WebAuthnの複雑さやエッジケースを処理し、組み込みのテレメトリを提供することで、開発を大幅に加速できます。SDKは、ユニットテスト用のモック可能なインターフェースも提供します（シミュレーターでは生体認証をテストできないため、これは重要です）。

**推奨:** ネイティブ実装の場合、Corbado
SDK（[iOS Swift Passkey SDK](https://github.com/corbado/corbado-ios)、[Android Kotlin Passkey SDK](https://github.com/corbado/corbado-android)）の使用をお勧めします。これは、本番環境のデプロイを通じて発見された数多くのエッジケースを処理し、追加のテレメトリとテストを提供します。

### 1.2 システムWebView実装: OAuthに適した認証

システムWebViewは、プラットフォームのネイティブなブラウザコンポーネントを使用して、アプリ内の認証を処理します。完全なネイティブ実装とは異なり、システムWebViewは実際のシステムブラウザ（iOSの[Safari](https://www.corbado.com/ja/blog/digital-credentials-api)、Androidの[Chrome](https://www.corbado.com/ja/blog/digital-credentials-api)）を使用してWebコンテンツを表示し、共有Cookie、保存された認証情報、および使い慣れたブラウザのセキュリティインジケーターを維持します。

**システムWebViewを選択すべきケース:**

- **アプリがOAuthベースのログインを使用している**: システムWebViewは、OAuth2/OIDCフローに推奨されるアプローチであり、安全な認証を提供します
- モバイルアプリで再利用したい既存のWebベースの認証がある
- ネイティブで再構築することなく、複数の認証方法（パスワード、ソーシャルログイン、パスキー）をサポートする必要がある
- Webとモバイル全体で単一の認証コードベースを維持したい

**主な利点:**

- **OAuthの互換性**: OAuth/OIDC認証フローに特化して設計されています
- **セキュリティインジケーター**: ユーザーには実際のURLとSSL証明書が表示され、信頼関係が構築されます
- **低い実装作業**: ネイティブコードは最小限で済みます
- **一貫したUX**: ユーザーがすでに信頼している使い慣れたブラウザのインターフェース

**プラットフォームのコンポーネント:**

- **iOS**: `ASWebAuthenticationSession`（認証フローに推奨）または
  `SFSafariViewController`（一般的なブラウジング）
- **Android**: [Chrome](https://www.corbado.com/ja/blog/digital-credentials-api)カスタムタブ (CCT)

GoogleやGitHubなどの主要企業は、既存のWeb認証ページのWebViewオーバーレイを介してモバイルアプリにパスキーログインを追加するために、このアプローチを採用しています。これは、完全なネイティブ認証の再構築がすぐに実現できない場合に適しています。

#### 1.2.1 iOSのシステムWebViewのオプション

iOSには、認証用の2つの主要なシステムWebViewコンポーネントが用意されています。

**ASWebAuthenticationSession**（認証に推奨）:

- OAuth/OIDCおよび安全なログインフローに特化して設計されています
- アプリが認証を求めていることをユーザーに自動的にプロンプトで通知します
- [Safari](https://www.corbado.com/ja/blog/digital-credentials-api)とCookieおよび認証情報を共有します
- iCloudキーチェーン経由でパスキーをサポートします

**SFSafariViewController**（一般的なブラウジング）:

- アプリ内で完全な[Safari](https://www.corbado.com/ja/blog/digital-credentials-api)の体験を提供します
- URLバーとセキュリティインジケーターを表示します
- iOS
  11以降ではSafariのCookieを共有しません。Safariのセッション共有が必要な場合は、[ASWebAuthenticationSession](https://www.corbado.com/blog/native-app-passkeys)を使用します。
- カスタマイズ性は低いですが、ユーザーにとってより信頼性があります

| 機能                 | ASWebAuthenticationSession | SFSafariViewController  |
| :------------------- | :------------------------- | :---------------------- |
| **主なユースケース** | 認証フロー                 | 一般的なWebブラウジング |
| **OAuth/OIDC**       | 非常に優れている           | 良好                    |
| **パスキー対応**     | あり                       | あり                    |
| **カスタマイズ性**   | 限定的                     | 最小限                  |

**アプリがOAuthベースのログインを使用している場合**、`ASWebAuthenticationSession`
は認証シナリオ専用に設計されており、セキュリティとユーザー体験の最適なバランスを提供するため、推奨される選択肢です。

#### 1.2.2 AndroidのシステムWebView: Chromeカスタムタブ

Chromeカスタムタブ (CCT) は、アプリ内にChromeを活用した認証体験を提供します。

**主な機能:**

- ChromeブラウザとCookieおよび認証情報を共有します
- URLとセキュリティインジケーターを表示します
- ツールバーの色とブランディングをカスタマイズできます
- より高速な読み込みのためのプレウォーミング

**OAuth統合**:
Chromeカスタムタブは、iOSの[ASWebAuthenticationSession](https://www.corbado.com/blog/native-app-passkeys)に相当するAndroidの機能であり、保存されているパスキーへのアクセスを維持しながら、優れたOAuthサポートを提供します。

### 1.3 埋め込みWebView実装: 追加の設定を伴うセッション制御

埋め込みWebViewは、アプリ内のWebコンテンツのレンダリングを完全に制御し、URLバーなしでCookie、セッション、ナビゲーションを直接操作できるようにします。ただし、この制御機能により、パスキー機能を有効にするための追加の技術的要件が発生します。

**埋め込みWebViewを選択すべきケース:**

- **ネイティブのような体験**: アプリがすでにカスタマイズされたWebView内に認証を埋め込んでネイティブのルックアンドフィールを維持しており、この一貫したユーザー体験を維持したい場合
- **セッション/Cookieの制御が必要**:
  OAuth認証が完了した後、アプリが認証トークンとセッション状態を直接操作する必要がある場合
- システムWebView認証が認証コードを返すが、埋め込みコンテキストにはセッションがない既存の認証フロー
- 複数の埋め込みWeb画面間で認証状態を維持する必要がある
- **ファーストパーティ認証のみ**: アプリが認証を直接処理する場合（サードパーティのパスキー実装についてはこちらを参照）
- ランタイム機能の検出を備えたAndroidX WebKit 1.12.1以上
- ログインのためのConditional
  UIの制限（埋め込みWebViewではサポートされていません）を受け入れる（管理設定には関係ありません）

**重要なコンテキスト:**

多くのアプリではハイブリッドなアプローチを使用しています。システムWebViewが最初のOAuth認証（パスキーがシームレスに機能する）を処理し、認証後に埋め込みWebViewに切り替えて設定でパスキーを管理します。問題は、埋め込みWebView内でパスキーを直接使用しようとする場合に発生します。

**技術的要件:**

埋め込みWebViewは、システムWebViewと比較して追加の設定が必要です。

1. **iOS**: Associated Domainsエンタイトルメント、AASAファイルの構成
2. **Android**: パスキー機能のためのAndroidX WebKit 1.12.1以上およびWebView
   WebAuthnの構成（機能の検出が必要）
3. **両方**: 適切に構成されたWell-known関連付けファイルとDigital Asset Links

**プラットフォームのコンポーネント:**

- **iOS**: `WKWebView`
- **Android**: `android.webkit.WebView`

**トレードオフ:**

- **中程度の複雑さ**: WebViewの構成（Android WebKit
  1.12.1以上）とエンタイトルメントのセットアップ（iOS）が必要です
- **パスキーの採用率が低め**: ユーザーはネイティブと比較してより多くの摩擦に遭遇する可能性があります
- **Conditional
  UIはサポートされていません**: 入力フィールドでのパスキーの自動入力は、Androidの埋め込みWebViewでは機能しません
- **限定的なプラットフォームのサポート**: 一部の機能が一貫して機能しない場合があります（例：パスキーの自動作成）

## 2. WebViewのオプションの概要

WebViewを介してパスキーを実装する場合、システムWebViewと埋め込みWebViewの違いを理解することが重要です。上記で概説した3つのアプローチ（ネイティブ実装、システムWebView、および埋め込みWebView）は、それぞれ異なるユースケースに対応しています。

iOSでは、アプリ内でWebコンテンツを表示するための複数のオプションがあります。

- **WKWebView**は、WebKitフレームワーク（iOS
  8で導入）の一部であるカスタマイズ可能なWebViewです。これにより、Webコンテンツの外観と動作を高度に制御できます。
- **SFSafariViewController**は、Appleが提供するビューコントローラであり、アプリ内の軽量なSafariブラウザとして機能します。Safariのエンジンを使用します。iOS
  11以降では、独立したCookieストアがあり、SafariのCookieを共有しません。Safariのセッション共有が必要な場合は、ASWebAuthenticationSessionを使用します。
- **SFAuthenticationSession /
  ASWebAuthenticationSession**は、OAuth/OpenIDやその他の安全なログインフロー向けに特化されたWeb認証セッションです（iOS
  11/12以降で利用可能）。これらも内部でSafariを利用しますが、認証フローに重点を置いており、共有Cookieやシングルサインオン (SSO) などを自動的に処理します。

Androidの主な選択肢は次のとおりです。

- **Android
  WebView**は標準のWebViewウィジェット（`android.webkit.WebView`）であり、本質的にはアクティビティに埋め込むことができるミニブラウザです。高度にカスタマイズ可能ですが、アプリのプロセスで実行されます。
- \*\*Chromeカスタムタブ (CCT)\*\*は、アプリのコンテキスト内でChromeを利用したタブを開く機能です。カスタムタブはアプリの一部として表示されますが、プレロード、共有Cookie、ユーザーの信頼を得るための使い慣れたURLバーなどの機能を備えたChromeブラウザ（インストールされている場合）によって機能が提供されます。

次のセクションでは、iOSとAndroidのこれらのWebViewタイプについて少し深く掘り下げ、パスキー認証フローにどれが最も適しているかを説明します。

## 3. iOSでのWebView

Appleのプラットフォームは、上記の3つのWebViewオプションを提供しています。どれを選択するかによって、アプリ内でパスキーをどれだけスムーズに使用できるかが変わります。

iOSでのさまざまなWebViewの動作をテストするには、アプリ[WebView - WKWebView and UIWebView rendering](https://apps.apple.com/de/app/webview-wkwebview-and-uiwebview-rendering/id928647773)をお勧めします。

### 3.1 WKWebView

![パスキー WKWebView](https://www.corbado.com/website-assets/6523ba7b664086bd796e4329_ios_wkwebview_example_24707076e0.PNG)

**WKWebView**は、iOS用の多目的なWebViewコンポーネントです。開発者は[WKWebView](https://www.corbado.com/blog/native-app-passkeys)を埋め込んで、UIと動作を高度に制御しながらWebコンテンツをレンダリングできます。[WKWebView](https://www.corbado.com/blog/native-app-passkeys)はSafariと同じレンダリングエンジンを使用するため、非常にパフォーマンスが高く、最新のWeb機能をサポートしています。理論的には、正しく構成されていれば、WKWebViewはWebAuthn（したがってパスキー）を処理できますが、セキュリティ上の理由から一部の高度なブラウザ機能が制限される可能性があることに注意してください。注意すべき点の1つは、WKWebViewはデフォルトでモバイルSafariとCookieやキーチェーンのデータを共有しないことです。WebViewセッションはSafariのセッションから分離されているため、ユーザーは最初からログインし直す必要がある場合があります。また、WKWebViewのコンテンツはアプリによって完全にカスタマイズできるため、ユーザーにはアドレスバーやSafariのUIが表示されません。これはブランディングには最適ですが、ページの正当性を確認するための手がかりが少なくなることを意味します（フィッシング対策の懸念）。一部のアプリはWKWebViewを悪用してスクリプトを挿入したり、コンテンツを変更したりしたため（たとえば、[TikTok](https://www.corbado.com/blog/tiktok-passkeys)はアプリ内ブラウザ経由で追跡用のJSを挿入したと指摘されています）、WKWebViewを安全でユーザーに信頼される方法で使用するように注意する必要があります。

### 3.2 SFSafariViewController

![パスキー SFSafariViewController](https://www.corbado.com/website-assets/6523ba92021afcb2b832569b_ios_sfsafariviewcontroller_example_4638988ed0.PNG)

**SFSafariViewController**は、アプリ内でのSafariの体験を提供します。[SFSafariViewController](https://www.corbado.com/blog/native-app-passkeys)でURLを開くと、実際のSafariブラウザで開くのとほぼ同じですが、ユーザーはアプリのUI内に留まります。パスキーに関する利点は非常に大きいです。これは本質的にSafariであるため、ユーザーのiCloudキーチェーンと保存されたパスキーにアクセスできます。iOS
11以降ではCookieは共有されないことに注意してください。これは、ユーザーがすでにサイトのパスキーを持っている場合、Safariがそれを見つけ、簡単なログインのためにConditional
UIのオートコンプリートを表示することさえできることを意味します。[SFSafariViewController](https://www.corbado.com/blog/native-app-passkeys)はカスタマイズ性が低く（ツールバーをあまり変更できません）、セキュリティとプライバシーの機能の多くを自動的に処理します。HTTPS用の南京錠アイコンとともにURLバーが表示されるため、ユーザーは正しいドメインにいると確信できます。一般的に、[SFSafariViewController](https://www.corbado.com/blog/native-app-passkeys)は生のWKWebViewよりも安全であると考えられており、実装も簡単です（Appleがドロップインとして提供しています）。主なトレードオフは、ルックアンドフィールに対するある程度の制御を犠牲にすることです。認証フローの場合、それは通常許容されます。ここでの優先事項はセキュリティとログインの容易さであり、SFSafariViewControllerはSafariのコンテキストを使用することでこれに優れています。

![iOSのwebview](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/i_OS_webviews_fe6e593538.jpg)

|                | WKWebView                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | SFSafariViewController                                                                                                                                                                                                                                                                                                                          |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ユーザー体験   | - **ネイティブな感覚:** 開発者はアプリのデザインに合わせて外観をカスタマイズできるため、ユーザーはWebコンテンツをアプリのネイティブな部分であると感じる可能性があります。<br/> - **自動入力:** Safariのデータによる自動入力が可能です。                                                                                                                                                                                                                                                                                               | - **シームレス:** ユーザーのSafariの設定を利用したシームレスなユーザー体験により、ネイティブアプリとブラウザ間で一貫したWebブラウジングが保証されます。                                                                                                                                                                                         |
| 開発者体験     | - **高度なカスタマイズ性:** 幅広いカスタマイズと構成が可能です。<br/> - **柔軟性:** Webコンテンツを操作するための多くのAPIがあります。                                                                                                                                                                                                                                                                                                                                                                                                | - **中程度のカスタマイズ性:** 特にWKWebViewと比較して、カスタマイズのオプションは限られています。<br/> - **シンプル:** WKWebViewと比較して実装が簡単です。                                                                                                                                                                                      |
| パフォーマンス | - **やや遅い:** 実装やWebコンテンツによっては、読み込み速度を最適化できますが、カスタム機能やインタラクションの追加処理により、SFSafariViewControllerと比較して遅くなる場合があります。                                                                                                                                                                                                                                                                                                                                               | - **やや速い:** 速度と効率を最適化したSafariエンジンを活用するため、通常はパフォーマンスが向上し、Webページの読み込み時間が短縮されます。                                                                                                                                                                                                       |
| 信頼と認識     | - **URL表示は不要:** WKWebViewは多くの場合URLを表示しないため、ユーザーがWebページを検証するのが難しくなります。悪意のあるアプリがこの動作を模倣し、認証情報をフィッシングする可能性があります。                                                                                                                                                                                                                                                                                                                                      | - **ブラウザのような体験:** Safariを使用してWebページをレンダリングし、「ブラウザのような」体験を提供します。ユーザーはURLを確認し、Safariの自動入力機能にアクセスできるため、使い慣れたインターフェースにより信頼が高まる可能性があります。                                                                                                    |
| 分離           | - **分離されている:** CookieとセッションはSafariから分離されています。ユーザーがWKWebViewに自動的にログインすることはありません。                                                                                                                                                                                                                                                                                                                                                                                                     | - **分離されている:** CookieとセッションはSafariから分離されています。ユーザーがSFSafariViewControllerに自動的にログインすることもありません。                                                                                                                                                                                                  |
| 脆弱性         | - **安全:** Appleのアプリサンドボックスにより本質的に安全ですが、動作とセキュリティはアプリの実装に依存します。正しく実装されていない場合、潜在的な脆弱性があります。                                                                                                                                                                                                                                                                                                                                                                 | - **より安全:** フィッシング対策や悪意のあるWebサイトの警告など、Safariの組み込みセキュリティ機能の恩恵を受けます。これらの機能とSafariに対するユーザーの親しみやすさから、一般に、Webコンテンツの表示においてWKWebViewよりも安全であると考えられています。                                                                                     |
| その他         | - **利用できない機能:** セキュリティ上の懸念と、WKWebViewがアプリケーションコンテキストで実行されるため、一部のブラウザ機能（WebAuthnなど）には完全にアクセスできない場合があります。<br/> - **JavaScriptの挿入:** TikTokなどの一部のアプリは、アプリ内のWKWebViewに追跡用のJavaScriptを挿入したり、ユーザーのコントロールを制限したりします（Facebookなど）。<br/> - **プライバシーの問題:** プライバシーに関する[コミュニティのフィードバック](https://gist.github.com/chrmod/a5c71f9e7f86782d47eb1734df440260)が多くなっています。 | - **JavaScriptの挿入なし:** アプリからのJavaScriptの実行を許可しないため、セキュリティとプライバシーが強化されます。また、JavaScriptのアラートや確認をサポートしていないため、特定のWebページでのユーザー体験に影響を与える可能性があります。<br/> - リーダーモード: クリーンで読みやすいバージョンの記事を表示するリーダーモードを提供します。 |

### 3.3 SFAuthenticationSession / ASWebAuthenticationSession

**SFAuthenticationSession / ASWebAuthenticationSession**
– これらのクラス（後者は新しいSwift向けの名称）は、OAuthやOpenID
Connectなどのログインフロー専用に構築されています。Webページを介してユーザーを（おそらく外部のIdPに対して）認証する必要がある場合、iOSではこれらのセッションが推奨される選択肢です。これらは内部でSafariブラウザを利用し、SafariとCookieやストレージを共有するという点でSFSafariViewControllerに非常によく似ています。主な違いは、[SFAuthenticationSession](https://www.corbado.com/blog/native-app-passkeys)は常にWebページを使用して認証することをアプリがユーザーに（ユーザーの認識のために）プロンプトで通知し、利用可能な場合はユーザーの既存のSafariセッションを自動的に使用することです。

利点はシームレスな[SSO](https://www.corbado.com/blog/passkeys-single-sign-on-sso)体験です。ユーザーがSafariですでにプロバイダーにログインしている場合、このセッションはそのCookieを使用して別のログインを回避できます。パスキーの場合、これはSafari/iCloudキーチェーンに保存されているパスキー認証情報をここでも使用できることを意味するため重要です。Appleの公式ガイダンスでは、ログインフローのように見えるものにはASWebAuthenticationSessionを使用することを推奨しています。利点は、プライバシーの強化（アプリは認証情報やCookieを認識せず、Safariが処理します）と、組み込みの[SSO](https://www.corbado.com/blog/passkeys-single-sign-on-sso)サポートです。欠点は、認証フローに限定されていることです（アプリ内で任意のWebコンテンツをレンダリングするだけのためには使用しません）。要約すると、iOSでWebViewアプローチを選択する場合、ASWebAuthenticationSessionは安全であり、Safariと状態を共有し、認証専用に構築されているため、パスキーを実装するための最良の選択であることが一般的です。

## 4. AndroidでのWebView

AndroidでのWebViewの選択は、従来のWebViewとChromeカスタムタブの間で行われます。

AndroidでのさまざまなWebViewの動作をテストするには、[WebView vs Chrome Custom Tabs](https://play.google.com/store/apps/details?id=com.ansbilisim.webviewvscustomchrometabs&hl=en_US)アプリをお勧めします。

### 4.1 Android WebView

![パスキー Android WebView](https://www.corbado.com/website-assets/6523ba9e959c16f8fec2e8c8_android_webview_example_0cd6d26c55.jpg)

**Android WebView**
(android.webkit.WebView) は、アクティビティのレイアウトにWebページを埋め込むことができるコンポーネントです。WKWebViewと同様に完全な制御を提供します。ナビゲーションの傍受、JavaScriptの挿入、UIのカスタマイズなどが可能です。また、アプリのプロセス内で実行されます。パスキーにWebViewを使用するということは、アプリがWebログインページを読み込み、そのページがWebAuthnパスキーのセレモニーを開始できることを意味します。最新のAndroid
WebViewはWebAuthnをサポートしています（デバイスのWebView実装がAndroid System
WebViewまたはChromeコンポーネント経由で最新である場合）。重要な考慮事項の1つは、デフォルトではAndroid
WebViewはユーザーのChromeブラウザとCookieや保存された認証情報を共有しないことです。そのため、WebViewで作成または使用されたパスキーがChromeに認識されない場合があり、その逆も同様です。この分離はセキュリティには良いことですが（アプリはブラウザのCookieを読み取れません）、ユーザーがすでにChromeで認証されている場合でも、再度ログインを強制する可能性があります。もう1つの問題は信頼です。プレーンなWebViewにはURLやSSLのロックアイコンが表示されないため、ユーザーはフィッシングされないようにアプリを完全に信頼する必要があります。Googleは、潜在的なフィッシングのリスクがあるため、Google
OAuthサインインにWebViewを使用することを禁止しています。パフォーマンスの面では、WebViewは問題ありませんが、特に重いページを読み込む場合、ユーザーのデフォルトのブラウザを使用するよりも遅くなったり、メモリを消費したりする可能性があります。

### 4.2 Chromeカスタムタブ (CCT)

![パスキー Chrome カスタムタブ (CCT)](https://www.corbado.com/website-assets/6523baa76223bf541db3ed47_android_chrome_custom_tab_example_2c9fa9233b.jpg)

\*\*Chromeカスタムタブ (CCT)\*\*はハイブリッドなアプローチです。これらは、アプリの一部のように見えるChromeレンダリングページをアプリから開くことを可能にします。ツールバーの色をカスタマイズしたり、アプリのロゴを追加したりできますが、コンテンツは別のプロセスでChromeによってレンダリングされます。パスキーの場合、[CCT](https://www.corbado.com/blog/native-app-passkeys)にはいくつかの利点があります。ユーザーのCookieと認証情報をChromeブラウザと共有するため、ユーザーがChrome（Googleパスワードマネージャー）を介してパスキーを保存している場合、カスタムタブはそれにアクセスできます。ユーザーには実際のURLとセキュリティインジケーターも表示され、信頼が構築されます。多くの場合、パフォーマンスも優れています。より高速な読み込みのために、バックグラウンドでChromeを「ウォームアップ」することができます。そして重要なのは、セキュリティが強力であることです。本質的にChromeアプリであるため、Googleセーフブラウジングなどによりセッションが保護され、アプリがページに任意のスクリプトを挿入することはできません（特定の攻撃を防ぎます）。

欠点は、ユーザーがサポートされているブラウザ（通常はChrome）をインストールし、最新の状態に保つ必要があることです。ほとんどのAndroidユーザーはそうしていますが、一部の地域の特定のデバイスでは、これが問題になる可能性があります。全体として、Androidで埋め込みWebアプローチを採用する場合、統合とセキュリティのバランスが良いため、パスキーのフローにはChromeカスタムタブが推奨されます。実際、認証にデフォルトのブラウザを活用するという点で、iOSのSFSafariViewController/ASWebAuthSessionに多くの点で似ています。

（余談:
AppleのWKWebView対SFSafariViewControllerとAndroidのWebView対[CCT](https://www.corbado.com/blog/native-app-passkeys)には多くの類似点があります。Safari
VCとChrome
Tabsはどちらもブラウザの状態を共有し、より優れたセキュリティを提供しますが、WKWebView/Android
WebViewはより多くの制御を提供しますが、Webコンテンツを分離します。パスキーの場合、状態（Cookie、認証情報ストア）を共有して、パスキーにシームレスにアクセスして作成できるようにすることが通常は望ましいです。）

![androidのwebview](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/android_webviews_b411ad674d.jpg)

| 機能               | WebView                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Chromeカスタムタブ                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **ユーザー体験**   | - **柔軟性:** Webコンテンツの操作や、JavaScriptダイアログ、権限リクエストの処理など、ユーザーインタラクションを管理するための豊富なAPIセットを提供します。<br/> - **一貫性:** 特に多様なWebコンテンツにおいて、一貫したUXを管理するのは困難な場合があります。                                                                                                                                                                                                                                   | - **ブラウザの機能:** データセーバーやデバイス間で同期される自動入力などの機能を共有します。<br/> - **戻るボタン:** 統合された戻るボタンにより、ユーザーは簡単にアプリに戻ることができます。<br/> - **依存性:** Chromeアプリに依存しており、すべてのユーザーのデバイスで利用可能または更新されているとは限りません。<br/> - **ブラウザへのリダイレクト:** 特定の機能はユーザーをChromeアプリにリダイレクトし、ユーザー体験を妨げる可能性があります。<br/> - **部分的なカスタムタブ:** 画面の一部のみをChromeカスタムタブに使用し、残りの部分にネイティブアプリを表示できます。<br/> - **サイドシート:** 横向きモードや大画面デバイスでは、Chromeカスタムタブは画面の片側にのみ表示され、画面の残りの部分にはネイティブアプリが表示されます。 |
| **開発者体験**     | - **高度なカスタマイズ性:** 広範なカスタマイズのオプション/ニーズを提供します。<br/> - **インタラクティビティ:** Webコンテンツを操作し、ユーザーインタラクションを管理するための多数のAPIを提供します。                                                                                                                                                                                                                                                                                         | - **カスタマイズ性:** ツールバーの色、アクションボタン、下部ツールバー、カスタムメニューアイテム、イン/アウトのアニメーションをカスタマイズできます。<br/> - **コールバック:** 外部ナビゲーション時にアプリケーションにコールバックを提供します。<br/> - **セキュリティ機能:** すぐに使える機能を提供し、リクエスト、権限の付与、Cookieストアを管理する必要をなくします。                                                                                                                                                                                                                                                                                                                                                                    |
| **パフォーマンス** | - **平凡なパフォーマンス:** Chromeカスタムタブ (CCT) と同レベルのパフォーマンスを提供できない場合があります。                                                                                                                                                                                                                                                                                                                                                                                   | - **プレウォーミング:** ページの読み込み時間を短縮するために、バックグラウンドでのブラウザのプレウォーミングとURLの推測的な読み込みが含まれます。<br/> - **優先度:** カスタムタブを起動するアプリの重要度を「フォアグラウンド」レベルに引き上げることで、使用中にアプリが排除されるのを防ぎます。                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| **信頼と認識**     | - **URLとSSLが非表示**: WebViewでは、URLとSSLの情報は本質的に表示されません。アプリ開発者がこれらの機能を実装しない限り、ユーザーは正しいWebサイトにいるのか、フィッシングサイトにいるのかを知ることができません。                                                                                                                                                                                                                                                                              | - **URLとSSLが表示される**: 実際のChromeブラウザを使用してページをレンダリングします。ユーザーはURLとSSL証明書（接続が安全であることを示す）を確認できます。これにより、ユーザーはフィッシングサイトにいないという確信を持てる可能性があります。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| **分離**           | - **アプリのプロセス内で実行:** アプリに悪意のあるコードの実行を許可する脆弱性がある場合、WebViewが侵害されるリスクがあります。ただし、WebViewもアップデートを受け取りますが、その動作とセキュリティは、それを使用するアプリにより依存する可能性があります。<br/> - **Cookie / セッションの共有なし:** デバイスのメインブラウザとCookieやセッションを共有しないため、分離は提供されますが、ユーザーは再度ログインする必要がある場合があります。                                                 | - **Chromeのプロセス内で実行:** カスタムタブはChromeの一部であるため、同じプロセスで実行され、Chromeと同じセキュリティアップデートおよび機能を備えています。<br/> - **共有Cookieと権限モデル:** ユーザーがサイトに再度サインインしたり、権限を再付与したりする必要がないようにします。<br/> - **Chromeの設定と環境設定:** Chromeの設定と環境設定を利用します。                                                                                                                                                                                                                                                                                                                                                                               |
| **脆弱性**         | - **認証情報を盗むコールバック:** 潜在的な脆弱性として、JavaScriptが必要な場合があり、これにより他のアプリが悪意のあるコードを実行する可能性が生じます。たとえば、[ユーザー名とパスワードを傍受しようとするコールバックの登録](https://arstechnica.com/gadgets/2021/07/google-boots-google-play-apps-for-stealing-users-facebook-passwords/)などです。<br/> - **フィッシング:** さらに、悪意のあるアプリがフィッシングの試みとして、リンクフローを模倣した別のWebページを開く可能性があります。 | - **Googleセーフブラウジング:** Googleのセーフブラウジングを採用して、ユーザーとデバイスの両方を危険なサイトから保護します。<br/> - **安全なブラウザの装飾:** ユーザーが操作している正確なURLを常に確認できるようにし、Webサイトの証明書情報を表示できるようにして、フィッシングのリスクを軽減します。さらに、カスタムタブではJavaScriptの挿入は許可されていません。                                                                                                                                                                                                                                                                                                                                                                         |
| **その他**         | - **GoogleはGoogleアカウントへのログインのためのWebViewを禁止しました**                                                                                                                                                                                                                                                                                                                                                                                                                         |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |

## 5. 技術的なセットアップ要件

どのアプローチを選択する場合でも、パスキー機能を有効にするには特定の技術的要件を満たす必要があります。このセクションでは、Well-known関連付けファイル、iOSのエンタイトルメント、およびAndroid
WebViewの構成に関する包括的なガイダンスを提供します。

**管理対象デバイスに関する注意事項:**
モバイルデバイス管理 (MDM) ポリシーが認証情報の保存を制御している管理対象デバイスでは、パスキーの動作が大きく変わります。管理対象デバイスでのパスキーのテストについては、管理対象のiOSおよびAndroidデバイスでのパスキーを参照してください。

### 5.1 Well-known関連付けファイル (ネイティブおよび埋め込み)

ネイティブおよび埋め込みWebViewのフローでは、アプリとWebドメイン間の暗号化による信頼を確立するために関連付けファイルが必要です。システムWebView（ASWebAuthenticationSession）およびChromeカスタムタブでは、アプリとサイトの関連付けは必要ありません。

#### 5.1.1 iOS: Apple-App-Site-Association (AASA) ファイル

![ios アプリ ネイティブ パスキー 関連付け](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/ios_app_native_passkeys_association_7dec89b433.png)

AASAファイルは、iOSアプリとWebドメインの間の接続を確立し、両方のプラットフォームでパスキーが機能するようにします。

**ファイルの場所**: `https://yourdomain.com/.well-known/apple-app-site-association`

**構成要件**:

- ドメインの `/.well-known/apple-app-site-association` でホストする
- 有効なSSL証明書を使用してHTTPSで提供する
- Content-Type: `application/json`
- `.well-known` パスでのリダイレクトなし
- アプリのチームIDとバンドルIDを含める

**AASAファイルの例**:

```json
{
    "webcredentials": {
        "apps": ["TEAMID123.com.example.app"]
    }
}
```

**AASAのキャッシュとテスト**:

AppleはCDNを使用してAASAファイルを積極的にキャッシュするため（最大24〜48時間）、開発やテストの妨げになる可能性があります。開発中にキャッシュをバイパスするには:

1. テストデバイスでデベロッパーモードを有効にします
2. XcodeのAssociated Domainsに `?mode=developer` を追加します
3. これにより、iOSは強制的にサーバーから直接最新のAASAファイルを取得します

⚠️ **重要**: 本番環境のリリースで `?mode=developer`
を使用しないでください。このパラメーターは開発専用です。本番環境で使用すると、iOSがAASAファイルを正しく検出できなくなり、パスキー機能が壊れます。

**検証**:
[AppleのAASA Validator](https://developer.apple.com/account/ios/identifier/bundle)
を使用して、構成を確認してください。

#### 5.1.2 Android: Digital Asset Links (assetlinks.json)

![android アプリ ネイティブ パスキー 関連付け](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/android_app_native_passkeys_association_1be4600a63.png)

AndroidはDigital Asset Linksを使用して、アプリとWebサイトの関係を検証します。

**ファイルの場所**: `https://yourdomain.com/.well-known/assetlinks.json`

**構成要件**:

- ドメインの `/.well-known/assetlinks.json` でホストする
- 有効な証明書を使用してHTTPSで提供する
- Content-Type: `application/json`
- アプリのSHA256フィンガープリント（署名証明書から）を含める

**assetlinks.jsonファイルの例**:

```json
[
    {
        "relation": [
            "delegate_permission/common.handle_all_urls",
            "delegate_permission/common.get_login_creds"
        ],
        "target": {
            "namespace": "android_app",
            "package_name": "com.example.app",
            "sha256_cert_fingerprints": [
                "AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99"
            ]
        }
    }
]
```

**2つのrelationの意味**: ネイティブAndroidパスキーリクエストはWeb形式のRP ID（例:
`example.com`）を使用するため、Androidはドメインが署名されたアプリパッケージを信頼していることを検証する必要があります。Digital
Asset Linksは、relation文字列を通じてその証明を提供します。

| Relation                                     | 宣言内容                                                                          |
| :------------------------------------------- | :-------------------------------------------------------------------------------- |
| `delegate_permission/common.handle_all_urls` | 署名されたAndroidアプリがドメインのURLを処理できること (App Links)                |
| `delegate_permission/common.get_login_creds` | WebサイトとAndroidアプリがログイン認証情報 (パスワード / パスキー) を共有すること |

Googleの現在の[Credential Manager / パスキーのガイダンス](https://developer.android.com/training/sign-in/passkeys)では、**両方**を宣言することを推奨しています。`get_login_creds`
は認証情報共有に特化したrelationであり、`handle_all_urls` はApp Linksを有効にします。

とはいえ、ネイティブAndroidパスキーが機能するために `get_login_creds`
が**常に**必須というわけではありません。古い[FIDO2](https://www.corbado.com/glossary/fido2)
/ パスキーのパスでは、検証済みの `handle_all_urls`
の関連付けでアプリとドメインの証明として十分とみなされており、Androidは下位互換性のためにその動作を維持しています。[PayPal](https://www.corbado.com/blog/paypal-passkeys)のような本番アプリでは、実際の
`assetlinks.json` に `handle_all_urls`
のみを含めてネイティブパスキーを正常に使用しています。

新しい統合の場合は、Googleの推奨通りに両方のrelationを宣言してください。既存のアプリをデバッグする際は、公開されているファイルを確認します。`handle_all_urls`
が正しく構成されていれば、`get_login_creds`
が欠落していることだけではパスキーフローが壊れる理由にはなりません。

**検証**:
[GoogleのDigital Asset Links Generator](https://developers.google.com/digital-asset-links/tools/generator)
を使用して、構成を作成および確認してください。

### 5.2 iOSのエンタイトルメントの構成

iOSアプリがパスキー機能にアクセスするには、適切なエンタイトルメントが必要です。要件は、実装アプローチによってわずかに異なります。

#### 5.2.1 Runner.entitlements / YourApp.entitlements の理解

エンタイトルメントファイル（[Flutter](https://www.corbado.com/blog/flutter-passkeys-package)アプリでは多くの場合
`Runner.entitlements`、ネイティブiOSプロジェクトでは `YourApp.entitlements`
という名前）は、Appleのシステムによって付与される特別な権限と機能を定義します。パスキーの場合、このファイルでAssociated
Domainsを構成します。

**ファイルの場所**: 通常はXcodeプロジェクトの `ios/Runner/Runner.entitlements` にあります

#### 5.2.2 Associated Domains 機能

ネイティブ実装および埋め込みWebViewでは、アプリをWebドメインにリンクするためにAssociated
Domains機能が必要です。システムWebView（ASWebAuthenticationSession）はSafariコンテキストで実行されるため、これは必要ありません。

**Xcodeでの設定**:

1. Xcodeでプロジェクトを開きます
2. アプリのターゲットを選択します
3. 「Signing & Capabilities」タブに移動します
4. 「+ Capability」をクリックし、「Associated Domains」を追加します
5. `webcredentials:` プレフィックスを付けてドメインを追加します

**構成の例**:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.developer.associated-domains</key>
    <array>
        <string>webcredentials:yourdomain.com</string>
        <string>webcredentials:subdomain.yourdomain.com</string>
    </array>
</dict>
</plist>
```

#### 5.2.3 アプローチ別の要件

| アプローチ          | Associated Domains 要否 | 追加の構成                                 |
| :------------------ | :---------------------- | :----------------------------------------- |
| **ネイティブ実装**  | 必要                    | 専用の実装                                 |
| **システムWebView** | 不要                    | デフォルトのWebセットアップで機能します    |
| **埋め込みWebView** | 必要                    | AndroidX WebKit 1.12.1以上の構成が必要です |

**複数ドメイン**: アプリが複数のドメインと連携する必要がある場合は、Related Origin
Requests (ROR) が必要になる場合があります。

### 5.3 Android WebViewの構成 (埋め込みWebViewのみ)

Androidの埋め込みWebViewは、2つの異なるアプローチを通じてパスキーをサポートします。新しいWebKitベースのアプローチ（セクション5.3.1）と、古いJavaScriptブリッジアプローチ（セクション5.3.2）です。システムWebView（Chromeカスタムタブ）には構成は必要ありません。認証情報は自動的に機能します。

Androidでは、両方の実装アプローチを示す[公式のWebViewパスキーサンプル](https://github.com/android/identity-samples/tree/main/WebView)が提供されています。

#### 5.3.1 ネイティブWebAuthnサポート (WebKit 1.12.1以上、推奨)

ネイティブなパスキー処理と統合された最新のWebKit。このアプローチは、カスタムブリッジコードを必要とせずにネイティブのWebAuthnサポートを提供します。

**公式サンプル**:
[Webkit WebView MainActivity](https://github.com/android/identity-samples/blob/0f79816496df1897343b64aa31a4ba4ac3f85021/WebView/WebkitWebView/app/src/main/java/com/google/webkit/webviewsample/MainActivity.kt)

**要件**:

- AndroidX WebKit 1.12.1 以降（1.14.0以上を推奨）
- Digital Asset Links が構成されていること
- WebAuthn をサポートする WebView APK（機能検出で確認）
- 注: AndroidX Credentials ライブラリは WebView
  WebAuthn には不要であり、完全なネイティブ実装にのみ必要です

**実装**:

```kotlin
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewFeature

// Web Authenticationがサポートされているか確認
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_AUTHENTICATION)) {
    // Web Authenticationを有効にする
    WebSettingsCompat.setWebAuthenticationSupport(
        webView.settings,
        WebSettingsCompat.WEB_AUTHENTICATION_SUPPORT_FOR_APP
    )

    // JavaScriptを有効にする
    webView.settings.javaScriptEnabled = true
}
```

**重要なポイント**:

- **JavaScriptブリッジ不要**: WebViewでWebAuthnがネイティブに機能します
- **機能の検出が必要**: 実行時に必ず `WebViewFeature.WEB_AUTHENTICATION`
  を確認してください
- **Conditional UIはサポートされていません**:
  `mediation:"conditional"`（入力フィールドでのパスキー自動入力）は埋め込みWebViewでは機能しません
- **フォールバック戦略**: 機能が利用できない場合は、代わりにChromeカスタムタブを使用します

**バージョンの注意事項**:

- WebKit **1.12.1以降**を使用してください（1.12.0には実行時の可用性の問題がありました）
- 機能のサポートはユーザーのWebView
  APKのバージョンに依存します。デバイス上の古いAPKでは機能が公開されません

#### 5.3.2 従来のアプローチ: JavaScriptブリッジ (WebKit 1.12.0以前)

AndroidX WebKit
1.12.0以前では、埋め込みWebViewにネイティブなWebAuthnサポートは存在しませんでした。この古いアプローチでは、ネイティブなWebView
WebAuthnサポートを持たないデバイスのパスキーを処理するために、Webとネイティブのブリッジを使用します。

**公式サンプル**:

- [PasskeyWebListener (Bridge Handler)](https://github.com/android/identity-samples/blob/0f79816496df1897343b64aa31a4ba4ac3f85021/WebView/CredentialManagerWebView/PasskeyWebListener.kt)
- [JavaScript encode utilities](https://github.com/android/identity-samples/blob/0f79816496df1897343b64aa31a4ba4ac3f85021/WebView/CredentialManagerWebView/javascript/encode.js)

**使用すべきケース**: 古いAndroidバージョン、または従来のWebView実装を持つデバイスをサポートする場合。

チームは次のいずれかを行う必要がありました。

1. ChromeカスタムタブまたはAuth Tabを使用する（推奨）
2. カスタムのJavaScriptブリッジを構築する

詳細な実装については、[AndroidのCredential Manager WebView統合ガイド](https://developer.android.com/training/sign-in/credential-manager-webview)を参照してください。ただし、最新のアプリには**ネイティブなWebKit
1.12.1以上のアプローチを使用することを強くお勧めします**。

**推奨**: AndroidX WebKit
1.12.1以上でネイティブなWebAuthnサポートを使用します。実行時に利用できない場合は、共有認証情報による優れたパスキーサポートを提供するChromeカスタムタブにフォールバックします。

### 5.4 Origins、Related Origins (ROR) およびWell-knownファイルの検証

ネイティブアプリにパスキーを実装する場合、アプリとWebドメイン間で信頼を確立する必要があります。このセクションでは、単一ドメイン、複数の関連ドメイン (ROR) の処理方法、およびWell-known関連付けファイルが正しく構成されているかを確認する方法について説明します。

#### 5.4.1 単一ドメインのセットアップ

単一のドメイン（例: `kayak.com`）を使用するアプリの場合は、次のものが必要です。

- iOS用の1つのAASAファイル（[https://kayak.com/.well-known/apple-app-site-association](https://kayak.com/.well-known/apple-app-site-association)）
- Android用の1つの[assetlinks.json](https://www.corbado.com/ja/blog/webauthn-relying-party-id-rpid-passkeys)（[https://kayak.com/.well-known/assetlinks.json](https://kayak.com/.well-known/assetlinks.json)）
- `webcredentials:kayak.com` で構成されたAssociated Domainsエンタイトルメント

#### 5.4.2 複数ドメインのためのRelated Origins (ROR)

[Related Origins](https://www.corbado.com/blog/webauthn-related-origins-cross-domain-passkeys)
(ROR) は、単一のパスキーセットが複数の関連ドメイン（例:
`kayak.com`、`kayak.de`、`kayak.co.uk`）で機能するようにするWebAuthnの機能です。
[ROR](https://www.corbado.com/blog/webauthn-related-origins-cross-domain-passkeys)は、各サイトの
`/.well-known/webauthn`
エンドポイントを使用して関連するオリジンを定義し、AASAやassetlinksファイルは使用しません。

**重要なポイント**:

- [ROR](https://www.corbado.com/blog/webauthn-related-origins-cross-domain-passkeys)の構成: 各ドメインは、関連するオリジンのリストを含む
  `/.well-known/webauthn` をホストします
- アプリの関連付けファイル（AASA/assetlinks）: アプリを対応するWebサイトにマッピングするためにのみ使用されます
- [iOS 18](https://www.corbado.com/blog/ios-18-passkeys-automatic-passkey-upgrades)+の埋め込みWebView: 正しく構成されていれば[ROR](https://www.corbado.com/blog/webauthn-related-origins-cross-domain-passkeys)をサポートします
- Associated
  Domainsエンタイトルメント: アプリが認証する必要のあるすべてのドメインを含めます

**構成の例**:

アプリが `kayak.com` および `kayak.de`
と連携する場合、両方のドメインで次のことを行う必要があります。

- 同じチームIDとバンドルIDを持つ、それぞれのAASAファイルをホストする
- アプリのAssociated Domainsエンタイトルメントにリストされている
- 適切に構成され、アクセス可能なWell-knownファイルがある

#### 5.4.3 Well-knownファイルの検証

本番環境に移行する前に、Well-knownファイルが正しく構成され、アクセス可能であることを確認してください。AppleとGoogleは、ファイルの可用性を確認するためのCDNベースのテストURLを提供しています。

| ドメイン  | Apple AASA の検証                                                                                                                      | Google Digital Asset Links の検証                                                                                                                                                                                                 |
| :-------- | :------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| kayak.com | [テスト AASA ファイル](https://app-site-association.cdn-apple.com/a/v1/kayak.com?nocache=1)<br/>Apple CDN がファイルを取得できるか確認 | [テスト assetlinks.json](https://digitalassetlinks.googleapis.com/v1/statements:list/?source.web.site=https://www.kayak.com&relation=delegate_permission/common.handle_all_urls)<br/>Google が asset links にアクセスできるか検証 |
| kayak.de  | [テスト AASA ファイル](https://app-site-association.cdn-apple.com/a/v1/kayak.de?nocache=1)<br/>Apple CDN がファイルを取得できるか確認  | [テスト assetlinks.json](https://digitalassetlinks.googleapis.com/v1/statements:list/?source.web.site=https://www.kayak.de&relation=delegate_permission/common.handle_all_urls)<br/>Google が asset links にアクセスできるか検証  |

**これらのテストURLの使用**:

- リンクをクリックして、Apple/GoogleがWell-knownファイルを取得できるか確認します
- Appleの `?nocache=1`
  パラメーターは、CDNキャッシュをバイパスして強制的に最新の取得を行います
- これらのURLからファイルにアクセスできない場合、アプリでパスキー機能が動作しません
- 上記のURLパターンの `kayak.com` または `kayak.de` をご自身のドメインに置き換えてください

**テストの注意点**: すべてのドメインに適切に構成されたWell-knownファイルがあることを確認してください。いずれかのドメインでファイルが欠落していたり、誤って構成されていたりすると、そのドメインのパスキー機能が壊れる可能性があります。

**詳細情報**: ネイティブアプリでのWebAuthn [Relying Party](https://www.corbado.com/glossary/relying-party) ID

## 6. ネイティブアプリでのパスキー実装に関する推奨事項

適切な実装アプローチの選択は、アプリの認証アーキテクチャ、OAuth要件、およびセッション制御のニーズによって異なります。このデシジョンツリーを使用して、最適な方針を決定してください。

### 6.1 デシジョンツリー

次のフローチャートは、アプリの要件に基づいて適切な実装アプローチを選択するためのガイドです。

**各パスのクイックリファレンス:**

- **OAuthベースのログイン？** → システムWebView (ASWebAuthenticationSession /
  Chromeカスタムタブ)
- **ネイティブシェルでWeb認証を再利用？** → 設定付きの埋め込みWebView (WKWebView / Android
  WebView + WebKit 1.12.1+)
- **ネイティブファーストで構築？** → ネイティブ実装 (AuthenticationServices / Credential
  Manager)
- **再利用する既存のWeb認証がある？**
  → 素早く実装するにはシステムWebView。それ以外の場合は最適なUXのためのネイティブ実装

### 6.2 アプローチの比較: 採用の側面

各アプローチの主な側面におけるパフォーマンスは次のとおりです。

| アプローチ          | パスキーの作成                                          | パスキーの使用                                                                                                    | パスキーの管理                                      | 技術的複雑さ                         | OAuthのサポート                              | セットアップ時間 |
| :------------------ | :------------------------------------------------------ | :---------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------- | :----------------------------------- | :------------------------------------------- | :--------------- |
| **ネイティブ実装**  | **高い採用率**<br/>シームレスな生体認証、最高のUX       | **即座にサイレント**<br/>`preferImmediatelyAvailableCredentials` によりアプリ起動時に自動オーバーレイが表示される | **完全なネイティブ制御**<br/>アプリの設定に統合     | 中〜高<br/>プラットフォーム固有のAPI | 別途OAuthフローの実装が必要                  | 数週間〜数ヶ月   |
| **システムWebView** | **良好な採用率**<br/>ブラウザに近い体験、使い慣れている | **標準的なブラウザのUX**<br/>入力フィールドでのConditional UI、共有キーチェーン                                   | **ブラウザベース**<br/>ユーザーはブラウザ経由で管理 | **低**<br/>最小限のネイティブコード  | **優れている**<br/>OAuth専用に構築されている | 数日〜数週間     |
| **埋め込みWebView** | **採用率は低め**<br/>構成が必要                         | **ネイティブWebAuthnサポート**<br/>WebKit 1.12.1以上、Conditional UIなし                                          | **限定的な制御**<br/>ネイティブ統合なし             | **中〜高**<br/>WebViewの構成＋権限   | 構成が必要                                   | 1〜2週間         |

**側面の解説**:

- **パスキーの作成**: このアプローチを通じてユーザーがどれだけ簡単にパスキーを作成できるか
- **パスキーの使用**: 既存のパスキーを使用する際の認証体験
- **パスキーの管理**: ユーザーがパスキーを表示、編集、または削除する方法
- **技術的複雑さ**: 開発の労力と継続的なメンテナンス
- **OAuthのサポート**: アプローチがOAuth2/OIDC認証フローをどれだけうまく処理するか
- **セットアップ時間**: 一般的な実装のタイムライン

### 6.3 シナリオ別の具体的な推奨事項

#### 6.3.1 シナリオA: OAuthベースの認証 (最も一般的)

**推奨: システムWebView**

アプリがOAuth2、OIDC、またはソーシャルログインプロバイダー（Google、GitHub、Microsoftなど）を介して認証を行う場合、システムWebViewが最適な選択肢です。

- **iOS**: `ASWebAuthenticationSession` はOAuthフロー専用に構築されています
- **Android**: ChromeカスタムタブはシームレスなOAuth統合を提供します
- **利点**: 最小限のネイティブコード、認証情報の自動共有
- **実装**: Web認証ページにWebAuthnを追加し、システムWebView経由で読み込みます

**例**:
[kayak](https://www.corbado.com/blog/kayak-passkeys).comや[kayak](https://www.corbado.com/blog/kayak-passkeys).deなどの[旅行](https://www.corbado.com/passkeys-for-travel)アプリは、認証にOAuthを使用しています。システムWebViewにより、既存のOAuthインフラストラクチャを維持しながら、Web認証ページを通じてパスキーのサポートを追加できます。

#### 6.3.2 シナリオB: セッション制御のニーズがあるネイティブログイン

**推奨: ハイブリッドアプローチ**

最初のOAuth認証にはシステムWebViewを使用し、認証後のセッションには埋め込みWebViewを使用します。

1. **最初の認証**: システムWebViewがOAuth＋パスキーのログインを処理します
2. **セッション管理**:
   Cookie/セッションの制御が必要な認証済みのWebコンテンツのために、埋め込みWebViewに切り替えます
3. **技術的なセットアップ**: システムWebViewと埋め込みWebViewの両方の要件を構成します。Androidの場合は、AndroidX
   WebKit 1.12.1以上が含まれていることを確認してください（セクション5を参照）

**使用すべきケース**:
OAuthを介して認証を行うが、セッションの直接操作が必要な認証済みWebコンテンツを表示する必要があるアプリ。

#### 6.3.3 シナリオC: 新しいネイティブアプリまたはネイティブファースト

**推奨: ネイティブ実装**

ゼロから構築する場合、またはネイティブ画面がある場合は、完全にネイティブにします。

- **iOS**: AuthenticationServicesフレームワークを使用します
- **Android**: Credential Manager APIを使用します
- **利点**: 最高のUX、即時の認証、完全な制御
- **独自の利点**: `preferImmediatelyAvailableCredentials`
  を使用してアプリ起動時に[自動パスキーオーバーレイ](https://docs.corbado.com/passkey-ui-flows/native/passkey-login/overlay)を表示します。これはネイティブ実装専用であり、最高のコンバージョン率を提供します
- **SDKの推奨**: Corbado
  SDK（iOS、Android）を使用して、本番環境でテスト済みのエッジケース処理により開発を加速します

**新しいアプリの場合**: 初日からネイティブログインを構築することを強くお勧めします。最適なUXを実現し、将来のWebViewからネイティブへの移行を回避できます。

#### 6.3.4 シナリオD: Webベースのログインを持つ既存のアプリ

**推奨: 段階的な移行**

次の図は、増分的な移行パスを示しています。

各段階は前の段階に基づいて構築されるため、既存のユーザーを混乱させることなく段階的な改善が可能になります。

### 6.4 アプローチ別の主な技術的要件

| 要件                                     | ネイティブ                     | システムWebView                | 埋め込みWebView                |
| :--------------------------------------- | :----------------------------- | :----------------------------- | :----------------------------- |
| **Well-knownファイル (AASA/assetlinks)** | 必要                           | 不要                           | 必要                           |
| **iOS Associated Domains**               | 必要                           | 不要                           | 必要                           |
| **Android WebKit ライブラリ**            | 該当なし                       | 不要                           | **必要** (1.12.1以上)          |
| **Relying Party ID**                     | ドメインと一致させる必要がある | ドメインと一致させる必要がある | ドメインと一致させる必要がある |

詳細な構成手順については、セクション5を参照してください。

### 6.5 テストに関する推奨事項

ネイティブアプリでのパスキーのテストには、構造化された多層的なアプローチが必要です。テストピラミッドに従ってください。**ユニットテスト**（分離されたロジック）、**統合テスト**（シミュレーター/エミュレーターでのWebAuthnセレモニー）、および**システムテスト**（実機でのエンドツーエンド）です。

**必須のテストカテゴリ:**

- [ ] **コアジャーニー**: 登録、認証、デバイス間フロー、パスキーの削除
- [ ] **プラットフォームのカバレッジ**:
      iOS（ネイティブ）、Android（ネイティブ）、OSバージョンにわたるWebブラウザ
- [ ] **ドメインの関連付け**: AASAファイル（iOS）とDigital Asset
      Links（Android）にアクセスできることを確認する
- [ ] **キャンセルフロー**:
      OSのプロンプトと生体認証画面でのユーザーのキャンセルをテストする
- [ ] **エラー処理**: バックエンドの障害、ネットワークのタイムアウト、認証情報の不一致
- [ ] **エッジケース**: 画面ロックの無効化、iCloud/Googleパスワードマネージャーの無効化
- [ ] **OAuthフロー**: エンドツーエンドのOAuth＋パスキー統合の完了
- [ ] **管理対象デバイス**: MDMで制御された環境（管理対象デバイスのテストを参照）
- [ ] **サードパーティのマネージャー**:
      [1Password](https://www.corbado.com/blog/1password-passkeys-best-practices-analysis)、[Bitwarden](https://www.corbado.com/blog/passkey-analysis-bitwarden-developer-survey-2024)、[Dashlane](https://www.corbado.com/blog/dashlane-passkeys)の互換性
- [ ] **デバイス間認証**: QRコードフローとハイブリッドトランスポートのテスト
- [ ] **埋め込みWebView固有**: 埋め込みWebViewを使用する場合、AndroidでWebKit
      1.12.1以上の構成を確認する
- [ ] **本番環境の監視**: 成功率、失敗、および遅延のダッシュボード

自動化戦略、プラットフォーム固有の注意点、完全なプレフライトチェックリストなど、包括的なテストのガイダンスについては、専用のガイド「ネイティブiOSおよびAndroidアプリでのパスキーフローのテスト」を参照してください。

### 6.6 機会的な登録戦略

従来のログイン（パスワード、OAuth）が成功した**後**に、パスキーの作成をユーザーに促すことを検討してください。この段階的な変換アプローチには、次の利点があります。

- 既存の認証フローを中断しない
- ユーザーが拒否した場合にグレースフルデグラデーションを可能にする
- 変更を強制することなく、時間の経過とともにパスキーの採用率を高める
- 3つの実装アプローチすべてで機能する

**例**: システムWebView経由でOAuthログインした後、ネイティブプロンプト「[Face ID](https://www.corbado.com/faq/is-face-id-passkey)を使用してすばやくログインできるようにしますか？」を表示します。同意した場合は、システムWebViewで読み込まれたWebページを通じてパスキーを作成します。

## 7. Corbadoの活用方法

このガイドでは、ネイティブのパスキー実装において、関連付けファイル、[Related Origins](https://www.corbado.com/blog/webauthn-related-origins-cross-domain-passkeys)、エンタイトルメント、WebViewの仕様、フォールバック処理など、多くの基盤部分がいかに重要であるかを示しています。[Corbado Connect](https://www.corbado.com/connect)は、そのレイヤーを引き受けます。この記事で推奨されているシステムWebViewおよび埋め込みWebViewのアプローチに、パスキーのログイン、登録、管理を組み込むため、チームはプラットフォームごとにWebAuthnのセレモニーを手作業で構築することなくUXを提供できます。

[Video: Passkey first components](https://www.corbado.com/videos/connect/passkey-first-components.mp4) ([See how Corbado Connect ships this](https://www.corbado.com/connect))

- **パスキーファーストのログインコンポーネント:** iOSおよびAndroidで手作業で
  `navigator.credentials`
  とエラー処理を記述する代わりに、WebView内にレンダリングできる、すぐに使えるログインおよびパスキー一覧のUI。
- **機会的な登録:**
  アペンドフローは、従来のログイン後にパスキーの追加をユーザーに促します。これはセクション6.6の段階的な変換戦略と同じであり、ユーザーが拒否した場合はグレースフルなフォールバックを行います。
- **Relying Partyの構成を処理:**
  Corbadoはサーバー側で[Related Origins](https://www.corbado.com/blog/webauthn-related-origins-cross-domain-passkeys)と
  `.well-known`
  関連付けファイル（AASA、`assetlinks.json`）を管理するため、すべてのドメインとアプリでそれらを手作業で維持する必要がなくなります。
- **パスキー管理:**
  ユーザーは、設定コンポーネントからパスキーを一覧表示、追加、削除できます。これはこの記事で言及している埋め込みWebViewの管理ケースです。

また、ネイティブは手元にないデバイス上のWebView内で障害が発生するため、パスキーの問題を最も把握しにくい場所でもあります。認証の可観測性レイヤーである[Corbado Observe](https://www.corbado.com/observe)は、既存のアプリのその部分を測定します。つまり、[どのOSとアプリのバージョン](https://www.corbado.com/observe/passkey-errors)が実際にセレモニーを完了するか、関連付けファイルが本番環境で解決されるか、またはサイレントに失敗するか、そしてシステムWebViewのパスが実際のトラフィックで埋め込みWebViewのパスとどのように比較されるかを測定します。このガイドでは答えられない「どちらのアプローチが\_あなたの\_ユーザーに適しているか」という疑問に答えます。

このガイドで解説しているネイティブの設計上の決定（システムWebViewか埋め込みWebViewか）は維持しつつ、WebAuthnとRelying
Partyの負荷をCorbado
Connectに任せ、Observeを使用してその選択が本番環境で有効であることを確認します。

## 8. 結論

ネイティブ実装、システムWebView、埋め込みWebViewのいずれを介してパスキーを実装するかを決定することは、セキュリティ、ユーザー体験、開発の複雑さに影響を与える重要な設計上の選択です。万能の答えはありません。

**OAuthベースのアプリの場合**: システムWebView（ASWebAuthenticationSession、Chromeカスタムタブ）が推奨される出発点です。優れたOAuthサポート、最小限の実装労力、および認証情報の自動共有を提供します。

**ネイティブファーストのアプリの場合**: できるだけ早くネイティブに移行してください。ネイティブのパスキーログインは、WebView実装では提供できない[アプリ起動時の自動パスキーオーバーレイ](https://docs.corbado.com/passkey-ui-flows/native/passkey-login/overlay)を可能にする
`preferImmediatelyAvailableCredentials`
のような専用機能により、最もシームレスなUXを提供します。iOSとAndroidがパスキーをファーストクラスでサポートするようになった現在、現実世界での成功事例は高い採用率を示しています。オープンソースのSDKやプラットフォームのライブラリなどのツールは成熟しており、妥当な期間でのネイティブ統合が可能になっています。デバイス管理ポリシー、デバイス間の同期、サードパーティのプロバイダーに留意する必要がありますが、これらの課題は慎重なエンジニアリングとテストで管理できます。その結果、セキュリティが大幅に向上するとともに、使いやすさと速さでユーザーを喜ばせるアプリのログインが実現します。

**埋め込みWebViewフレームの要件がある場合**: 埋め込みWebViewは、現実世界の2つのシナリオで一般的に使用されます。まず、OAuthベースのアプリでは、多くの場合、最初のログインフローにシステムWebViewを使用し、セッション制御が必要な設定画面でパスキー管理オプションをレンダリングするために埋め込みWebViewに切り替えます（ただし、両方のフローにシステムWebViewを維持することでこれを簡略化するアプリもあります）。次に、パスキーを採用する前にWebViewフレームに認証フローをすでに埋め込んでいるアプリは、一貫性を保つためにこのパターンを継続します。ネイティブのWebAuthnサポート（AndroidX
WebKit
1.12.1以上）を備えた埋め込みWebViewには構成とセットアップ（権限、エンタイトルメント、WebView設定）が必要ですが、カスタムJavaScriptブリッジコードは不要になりました。Conditional
UIは埋め込みWebViewではサポートされていないことに注意してください。既存の埋め込み認証パターンを維持する場合、または認証後の画面のセッション/Cookie制御が必要な場合に、このアプローチを選択します。

結局のところ、ネイティブアプリのパスキーは、ユーザーの利便性とセキュリティの両方において大きな飛躍を意味します。ネイティブ、システムWebView、または埋め込みWebViewのいずれで実装されていても、フィッシングのリスクとユーザーのパスワード管理の負担を排除します。[VicRoads](https://www.corbado.com/blog/vicroads-passkeys)のネイティブアプリのパスキー統合のような現実世界の実装は、自動パスキーオーバーレイのような機能を使用して適切に実行された場合、ネイティブファーストのアプローチが最も高いユーザーの採用率と満足度をもたらすことを示しています。ユーザーフレンドリーな認証のベストプラクティスに従い、新しいアプリのネイティブファースト、OAuthフローのシステムWebView、または既存の埋め込みパターンの埋め込みWebViewなど、アプリのアーキテクチャに合った実装アプローチを選択することで、パスキーのビジョンである「誰にとってもシンプルで安全かつ楽しい認証」を真に実現するパスワードレスの生体認証ログインを提供できます。

## 9. トラブルシューティングチェックリスト

ネイティブアプリでパスキーが機能しない場合は、実装アプローチ別に以下の一般的な問題を確認してください。

### すべてのアプローチ: 関連付けファイルの問題

- [ ] 有効な証明書を使用してHTTPS経由で提供されているファイル
- [ ] 正しいMIMEタイプ: `application/json`
- [ ] `.well-known` パスでのリダイレクトがない
- [ ] iOS: AASAファイルのチームIDとバンドルIDが完全に一致している
- [ ] Android:
      [assetlinks.json](https://www.corbado.com/ja/blog/webauthn-relying-party-id-rpid-passkeys)のSHA256フィンガープリントが署名証明書と一致している
- [ ] [Relying Party](https://www.corbado.com/glossary/relying-party)
      IDがドメインと一致している（プロトコルなし、ポートなし）
- [ ] RP IDの末尾にスラッシュがない
- [ ] WebAuthnのオリジン: `https://your-domain.com`（app\:// ではない）

### ネイティブ実装

- [ ] iOS: XcodeでAssociated
      Domains機能が有効になっており、`webcredentials:yourdomain.com` が設定されている
- [ ] Android: AndroidManifest.xmlでDigital Asset Linksが宣言されている
- [ ] ユーザーが画面ロック（生体認証またはPIN）を有効にしている
- [ ] AppleのAASA ValidatorとGoogleのDigital Asset Linksツールでテストする
- [ ] Runner.entitlementsファイルに正しい関連ドメインが含まれていることを確認する

### システムWebView

- [ ] iOS: `ASWebAuthenticationSession`（推奨）または `SFSafariViewController`
      を使用している
- [ ] Android: Chromeカスタムタブを使用している（プレーンなWebViewではない）
- [ ] iOS: 必要に応じてAssociated Domainsが構成されていることを確認する
- [ ] Cookie/認証情報がシステムブラウザと共有されていることをテストする
- [ ] Web認証ページに適切なWebAuthn実装があることを確認する

### 埋め込みWebView

- [ ] iOS: 適切なエンタイトルメントで構成されている
- [ ] iOS: Associated Domainsに関連するすべてのドメインが含まれている
- [ ] iOS: AASAファイルにアクセス可能であり、適切にフォーマットされている
- [ ] iOS: 開発中は `?mode=developer` でテストする（本番環境では削除する）
- [ ] Android: プロジェクトにAndroidX WebKit 1.12.1以上（以降）が含まれている
- [ ] Android: `WebViewFeature.WEB_AUTHENTICATION` のランタイム機能チェック
- [ ] Android: `WEB_AUTHENTICATION_SUPPORT_FOR_APP` を指定して
      `setWebAuthenticationSupport()` が呼び出されている
- [ ] Android: WebView設定でJavaScriptが有効になっている
- [ ] Android: ユーザーのWebView
      APKのバージョンがWebAuthn機能をサポートしている（OSのバージョンではなく、機能検出を使用する）
- [ ] Conditional UIが使用されていない（埋め込みWebViewではサポートされていない）
- [ ] WebAuthn機能が利用できない場合は、Chromeカスタムタブにフォールバックする

### サードパーティプロバイダーの問題

- [ ] ユーザーがデフォルト以外の認証情報プロバイダー（[1Password](https://www.corbado.com/blog/1password-passkeys-best-practices-analysis)、[Bitwarden](https://www.corbado.com/blog/passkey-analysis-bitwarden-developer-survey-2024)など）をアクティブにしているか確認する
- [ ] プロバイダーがパスキーをサポートしていることを確認する（すべてのパスワードマネージャーがサポートしているわけではない）
- [ ] プラットフォームネイティブのクレデンシャルマネージャー（iCloudキーチェーン、Googleパスワードマネージャー）でテストする

### 一般的なエラーメッセージ

**"NotAllowedError: The request is not allowed by the user agent or the platform in the
current context"**

- 通常の意味: エンタイトルメントの欠落（iOS）またはWebView機能が利用不可/有効になっていない（Android埋め込みWebView）
- 確認事項: Associated
  Domainsの構成、AASAファイルのアクセス可能性、WebKitのバージョン、機能検出、`setWebAuthenticationSupport()`
  の呼び出し

**パスキーのプロンプトが表示されない**

- 可能性:
  AASA/[assetlinks.json](https://www.corbado.com/ja/blog/webauthn-relying-party-id-rpid-passkeys)が読み込まれていない、WebViewのタイプが間違っている、AASAファイルがキャッシュされている
- 試すこと: 関連付けファイルを検証する、テストのためにiOSで `?mode=developer`
  を使用する、WebViewのタイプを確認する

詳細なデバッグについては、ネイティブアプリの[Relying Party](https://www.corbado.com/glossary/relying-party)
IDに関する記事を参照してください。

### ステージングおよび開発環境の問題

よくある落とし穴: アクセスが制限された（IPホワイトリスト、VPNのみ）ステージング環境は失敗します。**AppleとGoogleのCDNが関連付けファイルを取得できる必要がある**からです。

- [ ] AASA/assetlinksファイルが**パブリックにアクセス可能**である（IPホワイトリストやVPNの要件がない）
- [ ] AppleのCDNがファイルに到達できることを確認する:
      `https://app-site-association.cdn-apple.com/a/v1/your-staging-domain.com?nocache=1`
- [ ] Googleがファイルに到達できることを確認する:
      `https://digitalassetlinks.googleapis.com/v1/statements:list/?source.web.site=https://your-staging-domain.com&relation=delegate_permission/common.handle_all_urls`

**本番環境のrpIDを使用したステージングサブドメイン:**

ステージング環境（例: `stg.login.example.com`）がrpIDとして本番環境ドメイン（例:
`example.com`）を使用している場合、AASAのルックアップはステージングのサブドメインではなく**rpIDドメイン**で発生します。これは次のことを意味します。

- [ ] ステージングのアプリバンドルIDを**本番環境**のAASAファイルに追加する
- [ ] ステージングで作成されたパスキーが本番環境のログインフローに表示されることに注意する（混乱の可能性）

**例（複数の環境で1つのAASAを共有する場合）:**

```json
{
    "webcredentials": {
        "apps": [
            "TEAMID123.com.example.app",
            "TEAMID123.com.example.app.dev",
            "TEAMID123.com.example.app.stg",
            "TEAMID123.com.example.app.pre"
        ]
    }
}
```

**推奨:**
環境間で認証情報が重複しないように、ステージングドメインに一致する別のステージングrpIDを使用します。これには、ステージングドメインにパブリックにアクセス可能なAASAファイルが必要です。

**`?mode=developer` の明確化:**

Associated Domainsの `?mode=developer`
パラメーターはAppleのCDNキャッシュをバイパスしますが、**アクセス可能性の要件はバイパスしません**。AASAファイルは、デバイスから（AppleのCDNを経由せず、直接）到達可能である必要があります。これは、AASAの変更を反復する開発中は役立ちますが、ステージングサーバーがIPホワイトリストに登録されている場合は役立ちません。

## 10. リソース

**Corbado ネイティブ SDK:**

- [iOS SDK (Swift)](https://github.com/corbado/corbado-ios)
- [Android SDK (Kotlin)](https://github.com/corbado/corbado-android)
- [Flutter パッケージ](https://pub.dev/packages/passkeys)

**プラットフォームのドキュメント:**

- [Apple: パスキーのサポート](https://developer.apple.com/documentation/authenticationservices/public-private_key_authentication/supporting_passkeys)
- [Google: Credential Manager](https://developer.android.com/training/sign-in/passkeys)

**検証ツール:**

- [Apple AASA Validator](https://developer.apple.com/account/ios/identifier/bundle)
- [Google Digital Asset Links Generator](https://developers.google.com/digital-asset-links/tools/generator)

## よくある質問

### モバイルアプリでのパスキー対応において、ネイティブ、システムWebView、埋め込みWebViewのどれを選ぶべきですか？

選択は認証アーキテクチャによって異なります。アプリがOAuth2やOIDCを使用している場合、システムWebView（iOSのASWebAuthenticationSessionやAndroidのChromeカスタムタブ）を使用すると実装の労力が最小限で済み、関連付けファイルのセットアップも不要です。新規のネイティブファーストアプリの場合、ネイティブ実装は優れたUXを提供しますが、埋め込みWebViewは、すでにWebViewフレーム内に認証を埋め込んでおり、ログイン後にセッションやCookieの制御が必要なアプリに適しています。

### iOSのパスキー認証におけるWKWebViewとSFSafariViewControllerの違いは何ですか？

SFSafariViewControllerはSafariのエンジンを利用し、SSLインジケーター付きのURLバーを表示してフィッシング対策を提供するため、認証フローにおいてより信頼性が高くなります。WKWebViewはUIのカスタマイズ性に優れていますが、Safariとは別の独立したCookieストアを持ち、パスキーを有効にするにはAssociated
DomainsエンタイトルメントとAASAファイルが必要です。また、URLバーを表示しないため、ユーザーからの信頼シグナルが低下します。

### パスキーのフローにおいて、Android WebViewではなくChromeカスタムタブを使用するべきなのはなぜですか？

Chromeカスタムタブは、ユーザーのChromeブラウザとCookieおよび保存された認証情報を共有するため、認証中にGoogleパスワードマネージャーに保存されたパスキーにアクセスできます。標準のAndroid
WebViewには独立したCookieストアがあり、URLやSSLインジケーターを表示しません。また、フィッシングのリスクがあるため、GoogleはGoogleアカウントのサインインにこれを使用することを明示的に禁止しています。

### 1Passwordのようなサードパーティのクレデンシャルマネージャーは、iOSおよびAndroidでのネイティブなパスキー作成にどのような影響を与えますか？

ユーザーが1Passwordなどのサードパーティのクレデンシャルマネージャーをアクティブなプロバイダーとして設定している場合、多くの場合、パスキーの作成と保存を傍受し、プラットフォームのネイティブなクレデンシャルマネージャー（iCloudキーチェーンまたはGoogleパスワードマネージャー）よりも優先されます。これは、パスキーがプラットフォームのキーチェーンではなくサードパーティのアプリに保存される可能性があることを意味し、デバイス間の同期とパスキーの管理動作に影響を与えます。

### MDMポリシーによりiCloudキーチェーンやGoogleパスワードマネージャーの同期が無効になっている管理対象のエンタープライズデバイスでは、パスキーはどうなりますか？

MDMポリシーで認証情報の同期が無効になっている場合、通常のコンシューマーシナリオとは異なり、パスキーはデバイスにバインドされ、代替デバイスにローミングできません。企業環境をターゲットとするアプリは、ユーザーが新しい管理対象デバイスを受け取った場合に対処するために、パスワードやマジックリンクのログインなどのフォールバック認証メカニズムを計画する必要があります。
