この記事では、ネイティブアプリ(iOS + Android)にパスキーを実装する方法を解説します。パスキー認証に推奨されるWebViewの種類についても学べます。

Vincent
Created: June 20, 2025
Updated: November 13, 2025

Passkeys Series: Native Apps
See the original blog version in English here.
60-page Enterprise Passkey Whitepaper:
Learn how leaders get +80% passkey adoption. Trusted by Rakuten, Klarna & Oracle
| アプローチ | 採用率 | パスキー作成 | パスキー使用 | パスキー管理 | 技術的複雑さ | OAuthサポート |
|---|---|---|---|---|---|---|
| ネイティブ実装 | 🟢🟢🟢 | 高い採用率、最高のUX、シームレスな生体認証 | 即時かつサイレントな認証 | ネイティブでの完全な制御 | 中〜高 | 別途フローが必要 |
| System WebView | 🟢🟢 | 良好な採用率、ブラウザに近い体験 | 標準的なブラウザUX、キーチェーン共有 | ブラウザベースの管理 | 低 | 非常に良い |
| Embedded WebView | 🟢 | 低い採用率、より多くの設定が必要 | ネイティブサポート(iOS & Android WebKit 1.12.1+)、Conditional UIは非対応 | 限定的な制御 | 中〜高 | N/A |
注: System WebViewとEmbedded WebViewはしばしば組み合わせて使用されます。System WebViewがログイン(認証情報の自動共有あり)を処理し、その後Embedded WebViewが設定画面でパスキー管理をレンダリングします。
主な決定要因:
最新のモバイルプラットフォームでは、ネイティブアプリにパスキーを統合するための3つの異なるアプローチが提供されています。それぞれ、ユーザー体験、技術的複雑さ、OAuthとの互換性においてトレードオフがあります。
ネイティブ実装:プラットフォームのAPI(iOSのAuthenticationServices、AndroidのCredential Manager)を使用して、アプリに直接パスキーフローを構築します。シームレスな生体認証で最高のユーザー体験を提供しますが、技術的な実装には中〜高度な労力が必要です。
System WebView:プラットフォームのブラウザコンポーネント(iOSのASWebAuthenticationSession / SFSafariViewController、AndroidのChrome Custom Tabs)を使用して認証を処理します。OAuthベースのログインフローに最適で、システムのブラウザと認証情報を共有します。
Embedded WebView:カスタマイズ可能なWebView(iOSのWKWebView、AndroidのWebView)をアプリ内に埋め込み、ネイティブアプリの骨格でウェブ認証を再利用します。URLバーなしでネイティブのような外観を提供し、WebViewのUIを完全に制御できます。パスキー機能を有効にするには、権限やエンタイトルメント(iOS)、およびAndroidX WebKit 1.12.1+でのWebView設定(Android)など、追加のセットアップが必要です。
適切な選択は、アプリの認証アーキテクチャ、OAuthプロバイダを使用しているかどうか、UIをどの程度制御する必要があるか、そしてネイティブファーストで構築しているかウェブコンポーネントを再利用しているかによって決まります。
パスキーのネイティブ実装は、プラットフォーム固有のAPIを使用してアプリのUIに直接認証フローを組み込むため、最適なユーザー体験を提供します。ユーザーは、プラットフォームネイティブのダイアログ、シームレスな生体認証、そして可能な限り最速のログイン時間というメリットを享受できます。
ネイティブ実装を選択すべき場合:
preferImmediatelyAvailableCredentialsを使用して、パスキーが利用可能な場合に自動的にパスキーのオーバーレイを表示できます。これにより、識別子を入力することなく最速のログイン体験が提供されます。主な利点:preferImmediatelyAvailableCredentials()
ネイティブ実装ではpreferImmediatelyAvailableCredentials()を活用して、パスキーが利用可能な場合にアプリ起動時に即座に表示される自動パスキーオーバーレイを作成できます。このユーザー名不要のフローは、ユーザーが最初に識別子を入力することなく自分のパスキーを即座に確認できるため、可能な限り最速のログイン体験を提供します。この機能はネイティブ実装に限定されており、WebViewの亜種では利用できません。
WebView実装ではConditional UI(入力フィールドでのパスキー提案)を使用できますが、ネイティブの自動オーバーレイは、アプリ起動時に即座に認証が開始されるため、より高いパスキー使用率で優れたUXを提供します。
技術要件の概要:
ネイティブでのパスキー統合には、アプリとウェブドメイン間の暗号化による信頼関係が必要です。これがないと、OSはすべてのWebAuthn操作を拒否します。主な要件は以下の通りです:
/.well-known/でホストされるアプリとドメインの関連付けファイル最大のメリットは、ウェブサイトで作成したパスキーがアプリでシームレスに機能し、その逆も同様であることです。
iOSでパスキーをネイティブに実装するには、AppleのAuthenticationServicesフレームワークを使用します。これはWebAuthn操作のためのAPIを提供します。
主なコンポーネント:
ASAuthorizationController:認証フローを管理ASAuthorizationPlatformPublicKeyCredentialProvider:パスキーリクエストを作成開発のヒント
?mode=developerを追加して、強制的に最新のファイルを取得します。Androidのネイティブパスキー実装では、Credential Manager API(下位互換性のために古いFIDO2 APIも使用可)を使用します。
主なコンポーネント:
CredentialManager:すべての認証情報操作のための中央APICreatePublicKeyCredentialRequest:パスキー登録用GetCredentialRequest:パスキー認証用注:Androidは現在、ネイティブアプリにおいてiOSのConditional UIのようなキーボード候補機能を欠いています(ただし、Conditional UIはウェブアプリでは機能します)。
パスキーをネイティブに実装するには、重要な課題と教訓があります。OSレベルでの統合は、異なるデバイスやOSバージョン間で問題を引き起こす可能性があります。
生のプラットフォームAPIを使用してパスキーを実装することもできますが、専用のSDKを使用すると、WebAuthnの複雑さやエッジケースを処理し、組み込みのテレメトリを提供することで、開発を大幅に加速できます。SDKはまた、単体テスト用のモック可能なインターフェースも提供します(シミュレータでは生体認証をテストできないため、これは非常に重要です)。
推奨: ネイティブ実装には、Corbado SDK(iOS Swift Passkey SDK、Android Kotlin Passkey SDK)の使用をお勧めします。これらは、本番環境でのデプロイを通じて発見された数多くのエッジケースを処理し、追加のテレメトリとテストを提供します。
Igor Gjorgjioski
Head of Digital Channels & Platform Enablement, VicRoads
Corbado proved to be a trusted partner. Their hands-on, 24/7 support and on-site assistance enabled a seamless integration into VicRoads' complex systems, offering passkeys to 5 million users.
何百万人にも採用されるパスキーを、素早く。CorbadoのAdoption Platformから始めましょう。
無料トライアルを開始System WebViewは、プラットフォームのネイティブブラウザコンポーネントを使用して、アプリ内で認証を処理します。完全なネイティブ実装とは異なり、System WebViewは実際のシステムブラウザ(iOSではSafari、AndroidではChrome)を使用してウェブコンテンツを表示し、共有Cookie、保存された認証情報、そしておなじみのブラウザのセキュリティインジケータを維持します。
System WebViewを選択すべき場合:
主な利点:
プラットフォームコンポーネント:
ASWebAuthenticationSession(認証フローに推奨)またはSFSafariViewController(一般的なブラウジング)GoogleやGitHubのような大手企業は、既存のウェブ認証ページにWebViewオーバーレイを介してモバイルアプリにパスキーログインを追加するためにこのアプローチを採用しました。これは、完全なネイティブ認証の再構築がすぐに実現可能でない場合にうまく機能します。
iOSは、認証のために2つの主要なSystem WebViewコンポーネントを提供します。
ASWebAuthenticationSession(認証に推奨):
SFSafariViewController(一般的なブラウジング):
| 機能 | ASWebAuthenticationSession | SFSafariViewController |
|---|---|---|
| 主な用途 | 認証フロー | 一般的なウェブブラウジング |
| OAuth/OIDC | 非常に良い | 良い |
| パスキーサポート | はい | はい |
| カスタマイズ性 | 限定的 | 最小限 |
アプリがOAuthベースのログインを使用している場合、ASWebAuthenticationSessionは認証シナリオ専用に設計されており、セキュリティとユーザー体験の最良のバランスを提供するため、推奨される選択肢です。
Chrome Custom Tabs(CCT)は、アプリ内でChromeを利用した認証体験を提供します。
主な機能:
OAuth統合:Chrome Custom TabsはiOSのASWebAuthenticationSessionに相当し、保存されたパスキーへのアクセスを維持しながら、優れたOAuthサポートを提供します。
Embedded WebViewは、アプリ内でレンダリングされるウェブコンテンツを完全に制御でき、URLバーなしでCookie、セッション、ナビゲーションを直接操作できます。しかし、この制御にはパスキー機能を有効にするための追加の技術要件が伴います。
Embedded WebViewを選択すべき場合:
重要なコンテキスト:
多くのアプリはハイブリッドアプローチを使用しています。最初のOAuth認証はSystem WebViewで処理し(パスキーはシームレスに機能)、認証後に設定画面でパスキーを管理するためにEmbedded WebViewに切り替えます。課題は、Embedded WebView内で直接パスキーを使用しようとするときに発生します。
技術要件:
Embedded WebViewは、System WebViewと比較して追加の設定が必要です。
プラットフォームコンポーネント:
WKWebViewandroid.webkit.WebViewトレードオフ:
WebViewを介してパスキーを実装する場合、System WebViewとEmbedded WebViewの違いを理解することが重要です。上記で概説した3つのアプローチ(ネイティブ実装、System WebView、Embedded WebView)は、それぞれ異なるユースケースに対応します。
iOSでは、アプリ内でウェブコンテンツを表示するための複数のオプションがあります:
Androidでの主な選択肢は次のとおりです:
android.webkit.WebView)で、アクティビティに埋め込むことができるミニブラウザのようなものです。高度にカスタマイズ可能ですが、アプリのプロセス内で実行されます。以下のセクションでは、これらのiOSおよびAndroid用のWebViewタイプについてもう少し詳しく掘り下げ、パスキー認証フローにどれが最適かを議論します。
Appleのプラットフォームは、上記の3つのWebViewオプションを提供します。どの選択をするかによって、アプリ内でのパスキーの使いやすさが変わってきます。
iOSでの異なるWebViewの挙動をテストするには、アプリWebView - WKWebView and UIWebView renderingをお勧めします。
WKWebViewは、iOS用の多機能なWebViewコンポーネントです。開発者はWKWebViewを埋め込んで、UIと動作を高度に制御しながらウェブコンテンツをレンダリングできます。WKWebViewはSafariと同じレンダリングエンジンを使用しているため、非常に高性能で、最新のウェブ機能をサポートしています。理論的には、正しく設定すればWKWebViewはWebAuthn(つまりパスキー)を扱うことができますが、セキュリティ上の理由から一部の高度なブラウザ機能が制限される場合があることに注意してください。注意すべき点として、WKWebViewはデフォルトでCookieやキーチェーンデータをMobile Safariと共有しません。そのため、WebViewセッションがSafariのセッションから隔離されているため、ユーザーは再度ログインする必要があるかもしれません。また、WKWebViewのコンテンツはアプリによって完全にカスタマイズできるため、ユーザーにはアドレスバーやSafariのUIが表示されません。これはブランディングには最適ですが、ユーザーがページの正当性を確認する手がかりが少なくなることを意味します(フィッシング対策の懸念)。一部のアプリはWKWebViewを悪用してスクリプトを注入したり、コンテンツを変更したりしています(例えば、TikTokはアプリ内ブラウザを介してトラッキング用のJSを注入していると指摘されました)。そのため、WKWebViewは安全でユーザーが信頼できる方法で使用するよう注意しなければなりません。
SFSafariViewControllerは、アプリ内でSafari体験を提供します。SFSafariViewControllerでURLを開くと、ユーザーがアプリのUI内に留まる点を除けば、本物のSafariブラウザで開くのとほとんど同じです。パスキーにとっての利点は大きいです。なぜなら、本質的にSafariなので、ユーザーのiCloud Keychainと保存されたパスキーにアクセスできるからです。ただし、iOS 11以降ではCookieは共有されません。これは、ユーザーがあなたのサイトのパスキーを既に持っている場合、Safariがそれを見つけ、簡単なログインのためにConditional UIのオートコンプリートを表示できることを意味します。SFSafariViewControllerはカスタマイズ性が低いですが(ツールバーはあまり変更できません)、多くのセキュリティとプライバシー機能を自動的に処理します。URLバーが表示され、HTTPSの南京錠アイコンも付いているため、ユーザーは正しいドメインにいるという安心感を得られます。一般的に、SFSafariViewControllerは生のWKWebViewよりも安全で、実装も簡単だと考えられています(Appleがドロップインとして提供)。主なトレードオフは、ルックアンドフィールの制御をいくらか犠牲にすることです。認証フローの場合、それは通常許容範囲内です。ここでの優先事項はセキュリティとログインの容易さであり、SFSafariViewControllerはSafariのコンテキストを使用することでこれを実現しています。
| WKWebView | SFSafariViewController | |
|---|---|---|
| ユーザー体験 | - ネイティブ感: 開発者がアプリのデザインに合わせてルックアンドフィールをカスタマイズできるため、ユーザーはウェブコンテンツがアプリのネイティブな一部であると感じるかもしれません。 - オートフィル: Safariからのデータによるオートフィルが可能です。 | - シームレス: ユーザーのSafari設定を使用するシームレスなユーザー体験により、ネイティブアプリとブラウザ間で一貫したウェブブラウジングを保証します。 |
| 開発者体験 | - 高度なカスタマイズ性: 広範なカスタマイズと設定が可能。 - 柔軟性: ウェブコンテンツと対話するための多くのAPIがあります。 | - 中程度のカスタマイズ性: 特にWKWebViewと比較して、カスタマイズオプションが限られています。 - シンプル: WKWebViewと比較して実装が簡単です。 |
| パフォーマンス | - 比較的遅い: 実装やウェブコンテンツによっては、読み込み速度を最適化できますが、カスタム機能やインタラクションの追加処理のため、SFSafariViewControllerに比べて遅くなる可能性があります。 | - 比較的速い: Safariエンジンを活用するため、通常はより良いパフォーマンスを提供します。速度と効率のために最適化されており、ウェブページの高速な読み込み時間を実現します。 |
| 信頼と認識 | - URL表示は必須ではない: WKWebViewはしばしばURLを表示しないため、ユーザーがウェブページを検証するのが難しくなります。悪意のあるアプリがこの挙動を模倣して認証情報をフィッシングする可能性があります。 | - ブラウザライクな体験: Safariを使用してウェブページをレンダリングし、「ブラウザライクな」体験を提供します。ユーザーはURLを確認し、Safariのオートフィル機能にアクセスできるため、見慣れたインターフェースにより信頼感が増す可能性があります。 |
| 分離 | - 分離されている: CookieとセッションはSafariから分離されています。ユーザーはWKWebViewに自動的にログインされません。 | - 分離されている: CookieとセッションはSafariから分離されています。ユーザーはSFSafariViewControllerにも自動的にログインされません。 |
| 脆弱性 | - 安全: Appleのアプリサンドボックスにより本質的に安全ですが、挙動とセキュリティはアプリの実装に依存します。正しく実装されない場合、脆弱性の可能性があります。 | - より安全: フィッシング対策や悪意のあるウェブサイトの警告など、Safariの組み込みセキュリティ機能の恩恵を受けます。これらの機能とユーザーのSafariへの慣れから、一般的にWKWebViewよりもウェブコンテンツを表示する上で安全だと考えられています。 |
| その他 | - 利用できない機能: セキュリティ上の懸念や、WKWebViewがアプリケーションコンテキストで実行されるため、一部のブラウザ機能(例:WebAuthn)が完全にアクセスできない場合があります。 - JavaScriptインジェクション: TikTokなどの一部のアプリは、アプリ内のWKWebViewにトラッキングJavaScriptを注入したり、ユーザーコントロールを制限したりします(例:Facebook)。 - プライバシー問題: プライバシーに関するコミュニティからのフィードバックが多いです。 | - JavaScriptインジェクションなし: アプリからのJavaScriptの実行を許可しないため、セキュリティとプライバシーが向上します。また、JavaScriptのアラートや確認をサポートしないため、特定のウェブページでのユーザー体験に影響を与える可能性があります。 - リーダーモード: 記事をクリーンで読みやすいバージョンで表示するリーダーモードを提供します。 |
SFAuthenticationSession / ASWebAuthenticationSession – これらのクラス(後者はより新しいSwiftフレンドリーな名前)は、OAuthやOpenID Connectのようなログインフロー専用に作られています。ウェブページを介してユーザーを認証する必要がある場合(おそらく外部のIdPに対して)、これらのセッションがiOSで推奨される選択肢です。これらはSFSafariViewControllerと非常に似ており、内部でSafariブラウザを利用し、Cookie/ストレージをSafariと共有します。重要な違いは、SFAuthenticationSessionは常にユーザーにウェブページを使用して認証しようとしていることをプロンプト表示し(ユーザーの認識のため)、利用可能な場合はユーザーの既存のSafariセッションを自動的に使用する点です。
その利点は、シームレスなSSO体験です。ユーザーがSafariでプロバイダにすでにログインしている場合、このセッションはそのCookieを使用して再度のログインを回避できます。パスキーにとってこれは重要です。なぜなら、Safari/iCloud Keychainに保存されているパスキー認証情報もここで使用できることを意味するからです。Appleの公式ガイダンスは、ログインフローのように見えるものにはASWebAuthenticationSessionを使用することです。利点はプライバシーの向上(アプリは認証情報やCookieを決して見ない、Safariが処理する)と、組み込みのSSOサポートです。欠点は、認証フローに限定されることです(アプリ内で任意のウェブコンテンツをレンダリングするためには使用しません)。要約すると、iOSでWebViewアプローチを選択する場合、ASWebAuthenticationSessionは、安全で、Safariと状態を共有し、認証専用に作られているため、パスキーを実装するための最良の選択肢となることが多いです。
Androidでは、WebViewの決定はクラシックなWebViewとChrome Custom Tabsの間で行われます。
Androidでの異なるWebViewの挙動をテストするには、アプリWebView vs Chrome Custom Tabsをお勧めします。
Android WebView (android.webkit.WebView) は、アクティビティのレイアウトにウェブページを埋め込むことができるコンポーネントです。ナビゲーションを傍受したり、JavaScriptを注入したり、UIをカスタマイズしたりできる点でWKWebViewに似ています。また、アプリのプロセス内で実行されます。パスキーにWebViewを使用するということは、アプリがウェブのログインページを読み込み、そのページが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は問題ありませんが、特に重いページを読み込む場合、ユーザーのデフォルトブラウザを使用するよりも遅くなったり、メモリを多く消費したりすることがあります。
**Chrome Custom Tabs (CCT)**はハイブリッドなアプローチです。アプリの一部のように見えるChromeでレンダリングされたページをアプリが開くことができます。ツールバーの色をカスタマイズしたり、アプリのロゴを追加したりできますが、コンテンツは別のプロセスでChromeによってレンダリングされます。パスキーにとって、CCTにはいくつかの利点があります。ユーザーのCookieと認証情報をChromeと共有するため、ユーザーがChrome(Googleパスワードマネージャー)経由でパスキーを保存している場合、Custom Tabはそれにアクセスできます。ユーザーは実際のURLとセキュリティインジケータも確認でき、これが信頼を築きます。パフォーマンスもしばしば向上します。Chromeはバックグラウンドで「ウォームアップ」して読み込みを高速化できます。そして重要なことに、セキュリティが強力です。本質的にChromeアプリなので、Googleセーフブラウジングのような機能がセッションを保護し、アプリはページに任意のスクリプトを注入できません(特定の攻撃を防ぎます)。
欠点は、ユーザーがChrome(またはサポートされているブラウザ)をインストールし、最新の状態に保つ必要があることです。ほとんどのAndroidユーザーはそうしていますが、特定の地域のデバイスではこれが問題になる可能性があります。全体として、Androidで埋め込みウェブアプローチを採用する場合、Chrome Custom Tabsは統合とセキュリティのバランスが良いため、パスキーフローに推奨されます。実際、これらは多くの点でiOSのSFSafariViewController/ASWebAuthSessionに類似しており、認証にデフォルトブラウザを活用しています。
(余談:AppleのWKWebView対SFSafariViewControllerとAndroidのWebView対CCTには多くの共通点があります。Safari VCとChrome Tabsは両方ともブラウザの状態を共有し、より良いセキュリティを提供しますが、WKWebView/Android WebViewはより多くの制御権を与える代わりにウェブコンテンツを分離します。パスキーの場合、パスキーがシームレスにアクセスおよび作成できるように、状態(Cookie、認証情報ストア)を共有することが通常望ましいです。)
| 機能 | WebView | Chrome Custom Tab | |
|---|---|---|---|
| ユーザー体験 | - 柔軟性: JavaScriptダイアログや権限リクエストの処理など、ウェブコンテンツとの対話やユーザーインタラクションの管理のための豊富なAPIセットを提供します。 - 一貫性: 特に多様なウェブコンテンツで一貫したUXを管理するのは難しい場合があります。 | - ブラウザ機能: データセーバーやデバイス間で同期されるオートコンプリートなどの機能を共有します。 - 戻るボタン: 統合された戻るボタンでユーザーが簡単にアプリに戻れるようにします。 - 依存性: Chromeアプリに依存しており、すべてのユーザーデバイスで利用可能または更新されているとは限りません。 - ブラウザへのリダイレクト: 特定の機能がユーザーをChromeアプリにリダイレクトし、ユーザー体験を中断させる可能性があります。 - 部分的なカスタムタブ: 画面の一部のみをChrome Custom Tabに使用し、残りの部分はネイティブアプリを表示できます。 - サイドシート: 横向きモードや大画面デバイスでは、Chrome Custom Tabは画面の片側のみに表示され、残りの画面にはネイティブアプリが表示されます。 | |
| 開発者体験 | - 高度なカスタマイズ性: 広範なカスタマイズオプション/ニーズを提供します。 - 対話性: ウェブコンテンツとの対話やユーザーインタラクションの管理のための多数のAPIを提供します。 | - カスタマイズ可能: ツールバーの色、アクションボタン、ボトムツールバー、カスタムメニュー項目、および出入りのアニメーションのカスタマイズが可能です。 - コールバック: 外部ナビゲーション時にアプリケーションにコールバックを配信します。 - セキュリティ機能: すぐに使える機能を提供し、リクエスト、権限付与、またはCookieストアを管理する必要がありません。 | |
| パフォーマンス | - 平凡なパフォーマンス: Chrome Custom Tabs (CCT) と同レベルのパフォーマンスを提供しない場合があります。 | - 事前ウォームアップ: バックグラウンドでのブラウザの事前ウォームアップやURLの投機的読み込みを含み、ページ読み込み時間を向上させます。 - 優先度: Custom Tabを起動するアプリの重要度を「フォアグラウンド」レベルに引き上げることで、使用中にアプリが強制終了されるのを防ぎます。 | |
| 信頼と認識 | - URLとSSLは非表示: URLとSSL情報はWebViewでは本質的に表示されません。アプリ開発者がこれらの機能を実装しない限り、ユーザーは正しいウェブサイトにいるのか、フィッシングサイトにいるのかを知ることができません。 | - URLとSSLは表示: ページのレンダリングに実際のChromeブラウザを使用します。ユーザーはURLとSSL証明書(接続が安全かどうかを示す)を見ることができます。これにより、ユーザーはフィッシングサイトにいないという安心感を得ることができます。 | |
| 分離 | - アプリのプロセス内で実行: アプリに悪意のあるコード実行を許す脆弱性がある場合、WebViewが侵害されるリスクがあります。しかし、WebViewも更新を受け取りますが、その動作とセキュリティはそれを使用するアプリに依存する場合があります。 - Cookie/セッション共有なし: デバイスのメインブラウザとCookieやセッションを共有しないため、分離を提供しますが、ユーザーに再度ログインを要求する可能性があります。 | - Chromeのプロセス内で実行: Chromeの一部であるため、Custom Tabsは同じプロセスで実行され、Chromeと同じセキュリティ更新と機能を持ちます。 - 共有Cookieジャーと権限モデル: ユーザーがサイトに再サインインしたり、権限を再付与したりする必要がないことを保証します。 - Chromeの設定と環境設定: Chromeの設定と環境設定を利用します。 | |
| 脆弱性 | - 認証情報を盗むためのコールバック: 潜在的な脆弱性として、時にはJavaScriptが必要となり、これが他のアプリに悪意のあるコードを実行する扉を開くことがあります。例えば、ユーザー名とパスワードを傍受しようとするコールバックを登録するなどです。 - フィッシング: さらに、悪意のあるアプリが、フィッシング目的でLinkフローを模倣した別のウェブページを開く可能性があります。 | - Googleセーフブラウジング: Googleのセーフブラウジングを採用し、ユーザーとデバイスの両方を危険なサイトから保護します。 - 安全なブラウザ装飾: ユーザーが常に対話している正確なURLを確認し、ウェブサイトの証明書情報を閲覧できることを保証し、フィッシングのリスクを低減します。さらに、カスタムタブはJavaScriptインジェクションを許可しません。 | |
| その他 | - GoogleはWebViewを禁止して、ユーザーをGoogleアカウントにログインさせています。 |
どの実装アプローチを選択するかにかかわらず、パスキー機能を有効にするためには特定の技術要件を満たす必要があります。このセクションでは、well-known関連付けファイル、iOSエンタイトルメント、およびAndroid WebViewの設定に関する包括的なガイダンスを提供します。
管理対象デバイスに関する注意: パスキーの動作は、モバイルデバイス管理(MDM)ポリシーが認証情報ストレージを制御する管理対象デバイスでは大幅に変わります。管理対象デバイスでパスキーをテストする方法については、「管理対象iOSおよびAndroidデバイスでのパスキー」を参照してください。
ネイティブフローおよびEmbedded WebViewフローでは、アプリとウェブドメイン間の暗号化による信頼を確立するために関連付けファイルが必要です。System WebView(ASWebAuthenticationSession)およびChrome Custom Tabsでは、アプリとサイトの関連付けは不要です。
The AASAファイルは、iOSアプリとウェブドメイン間の接続を確立し、パスキーが両方のプラットフォームで機能するようにします。
ファイルの場所: https://yourdomain.com/.well-known/apple-app-site-association
設定要件:
/.well-known/apple-app-site-association でホストするapplication/json.well-known パスにリダイレクトがないことAASAファイルの例:
{ "webcredentials": { "apps": ["TEAMID123.com.example.app"] } }
AASAのキャッシュとテスト:
AppleはAASAファイルを積極的(最大24〜48時間)にCDN経由でキャッシュするため、開発やテストが困難になることがあります。開発中にキャッシュをバイパスするには:
?mode=developer を追加する⚠️ 重要:本番リリースで ?mode=developer
を使用しないでください。このパラメータは開発専用です。本番環境で使用すると、iOSがAASAファイルを正しく検出できなくなり、パスキー機能が壊れます。
検証: AppleのAASA Validatorを使用して設定を検証してください。
Androidは、アプリとウェブサイト間の関係を検証するためにDigital Asset Linksを使用します。
ファイルの場所: https://yourdomain.com/.well-known/assetlinks.json
設定要件:
/.well-known/assetlinks.json でホストするapplication/jsonassetlinks.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" ] } } ]
検証: GoogleのDigital Asset Links Generatorを使用して設定を作成および検証してください。
iOSアプリがパスキー機能にアクセスするには、適切なエンタイトルメントが必要です。要件は実装アプローチによってわずかに異なります。
エンタイトルメントファイル(FlutterアプリではRunner.entitlements、ネイティブiOSプロジェクトではYourApp.entitlementsという名前が多い)は、Appleのシステムによって付与される特別な権限と機能を定義します。パスキーの場合、このファイルはAssociated
Domainsを設定します。
ファイルの場所: 通常、Xcodeプロジェクトのios/Runner/Runner.entitlementsにあります。
ネイティブ実装とEmbedded WebViewでは、アプリをウェブドメインにリンクするためにAssociated Domainsケーパビリティが必要です。System WebView(ASWebAuthenticationSession)はSafariのコンテキストで実行されるため、これは不要です。
Xcodeでの設定:
webcredentials:プレフィックスを付けてドメインを追加する設定例:
<?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>
| アプローチ | Associated Domainsが必要 | 追加設定 |
|---|---|---|
| ネイティブ実装 | はい | 専用の実装 |
| System WebView | 不要 | デフォルトのウェブ設定で動作 |
| Embedded WebView | はい | AndroidX WebKit 1.12.1+の設定が必要 |
複数ドメイン: アプリが複数のドメインで動作する必要がある場合は、Related Origin Requests (ROR) が必要になる場合があります。
AndroidのEmbedded WebViewは、AndroidX WebKit 1.12でネイティブのWebAuthnサポートが追加され、カスタムのJavaScriptブリッジコードが不要になりました。System WebView(Chrome Custom Tabs)は設定不要で、認証情報は自動的に機能します。
要件:
実装:
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 }
キーポイント:
WebViewFeature.WEB_AUTHENTICATIONを確認mediation:"conditional"(入力フィールドでのパスキーオートフィル)はEmbedded
WebViewでは動作しないバージョンに関する注意:
AndroidX WebKit 1.12.0以前は、Embedded WebViewにネイティブのWebAuthnサポートは存在しませんでした。チームは以下のいずれかを行う必要がありました:
古いAndroidバージョンやWebView APKが更新されていないデバイスをサポートする必要がある場合は、AndroidのCredential Manager WebView Integrationガイドでブリッジコードのアプローチを参照してください。しかし、現代のアプリにはネイティブのWebKit 1.12.1+アプローチを使用することを強く推奨します。
推奨: AndroidX WebKit 1.12.1+でネイティブWebAuthnサポートを使用してください。実行時に利用できない場合は、共有認証情報で優れたパスキーサポートを提供するChrome Custom Tabsにフォールバックしてください。
ネイティブアプリにパスキーを実装する際、アプリとウェブドメイン間の信頼を確立する必要があります。このセクションでは、単一ドメイン、複数の関連ドメイン(ROR)、そしてwell-known関連付けファイルが正しく設定されているかを確認する方法について説明します。
単一ドメイン(例:kayak.com)を使用するアプリの場合、以下が必要です:
webcredentials:kayak.comで設定されたAssociated DomainsエンタイトルメントRelated Origins
(ROR)は、単一のパスキーセットが複数の関連ドメイン(例:kayak.com、kayak.de、kayak.co.uk)で機能できるようにするWebAuthnの機能です。RORは、AASAやassetlinksファイルではなく、各サイトの/.well-known/webauthnエンドポイントを使用して関連オリジンを定義します。
キーポイント:
/.well-known/webauthnをホストします。設定例:
アプリがkayak.comとkayak.deで動作する場合、両方のドメインは以下の条件を満たす必要があります:
公開前に、well-knownファイルが正しく設定され、アクセス可能であることを確認してください。AppleとGoogleは、ファイルの可用性を確認するためのCDNベースのテストURLを提供しています。
| ドメイン | Apple AASA 検証 | Google Digital Asset Links 検証 |
|---|---|---|
| kayak.com | AASAファイルのテスト Apple CDNがファイルを取得できるか確認 | assetlinks.jsonのテスト Googleがアセットリンクにアクセスできるか検証 |
| kayak.de | AASAファイルのテスト Apple CDNがファイルを取得できるか確認 | assetlinks.jsonのテスト Googleがアセットリンクにアクセスできるか検証 |
これらのテストURLの使用方法:
?nocache=1パラメータは、CDNキャッシュをバイパスして最新の取得を強制しますkayak.comまたはkayak.deを自分のドメインに置き換えてくださいテストの注意点: すべてのドメインに正しく設定されたwell-knownファイルがあることを確認してください。いずれかのドメインでファイルが見つからない、または設定が間違っている場合、そのドメインのパスキー機能が壊れる可能性があります。
詳細情報: WebAuthn Relying Party ID in Native Apps
適切な実装アプローチの選択は、アプリの認証アーキテクチャ、OAuth要件、およびセッション制御の必要性に依存します。このデシジョンツリーを使用して、最善の道筋を決定してください。
まず、これらの主要な質問から始めます:
アプリはOAuthベースのログイン(OAuth2、OIDC、ソーシャルログインプロバイダ)を使用していますか?
ASWebAuthenticationSession を使用ネイティブのようなシェル(URLバーなし、完全なUI制御)でウェブ認証を再利用したいですか?
WKWebView + Associated DomainsエンタイトルメントWebView + AndroidX WebKit 1.12.1+の設定新しいネイティブアプリを構築しているか、ネイティブのログイン画面がありますか?
再利用したい既存のウェブ認証がありますか?
各アプローチが主要な側面でどのように機能するかを以下に示します:
| アプローチ | パスキー作成 | パスキー使用 | パスキー管理 | 技術的複雑さ | OAuthサポート | セットアップ時間 |
|---|---|---|---|---|---|---|
| ネイティブ実装 | 高い採用率 シームレスな生体認証、最高のUX | 即時、サイレントpreferImmediatelyAvailableCredentialsによりアプリ起動時の自動オーバーレイが可能 | ネイティブでの完全な制御 アプリ設定との統合 | 中〜高 プラットフォーム固有のAPI | 別途OAuthフローの実装が必要 | 数週間〜数ヶ月 |
| System WebView | 良好な採用率 ブラウザライクな体験、おなじみ | 標準的なブラウザUX 入力フィールドのConditional UI、共有キーチェーン | ブラウザベース ユーザーはブラウザ経由で管理 | 低 最小限のネイティブコード | 非常に良い OAuth専用設計 | 数日〜数週間 |
| Embedded WebView | 低い採用率 設定が必要 | ネイティブWebAuthnサポート WebKit 1.12.1+、Conditional UIなし | 限定的な制御 ネイティブ統合なし | 中〜高 WebView設定+権限 | 設定が必要 | 1〜2週間 |
側面の解説:
推奨:System WebView
アプリがOAuth2、OIDC、またはソーシャルログインプロバイダ(Google、GitHub、Microsoftなど)を介して認証する場合、System WebViewが最適な選択です:
ASWebAuthenticationSessionはOAuthフロー専用に設計されています例: kayak.comやkayak.deのような旅行アプリは、認証にOAuthを使用しています。System WebViewを使用することで、既存のOAuthインフラを維持しつつ、ウェブ認証ページを通じてパスキーサポートを追加できます。
推奨:ハイブリッドアプローチ
最初のOAuth認証にSystem WebViewを使用し、認証後のセッションにはEmbedded WebViewを使用します:
使用場面: OAuth経由で認証するが、その後、直接的なセッション操作が必要な認証済みウェブコンテンツを表示する必要があるアプリ。
推奨:ネイティブ実装
ゼロから構築するか、ネイティブ画面がある場合は、完全にネイティブに移行しましょう:
preferImmediatelyAvailableCredentialsを使用して、アプリ起動時に自動パスキーオーバーレイを表示します。これはネイティブ実装専用であり、最高のコンバージョン率を提供します。新しいアプリの場合: 初日からネイティブログインを構築することを強くお勧めします。これにより、最適なUXが実現し、将来のWebViewからネイティブへの移行を回避できます。
推奨:段階的移行
この段階的なアプローチにより、既存のユーザーを混乱させることなく、段階的な改善が可能です。
| 要件 | ネイティブ | System WebView | Embedded WebView |
|---|---|---|---|
| Well-knownファイル(AASA/assetlinks) | 必須 | 不要 | 必須 |
| iOS Associated Domains | 必須 | 不要 | 必須 |
| Android WebKit ライブラリ | 適用外 | 不要 | 必須(1.12.1+) |
| Relying Party ID | ドメインと一致する必要あり | ドメインと一致する必要あり | ドメインと一致する必要あり |
詳細な設定手順については、セクション5を参照してください。
ネイティブアプリでのパスキーのテストには、構造化された多層的なアプローチが必要です。テストピラミッドに従ってください:単体テスト(分離されたロジック)、統合テスト(シミュレータ/エミュレータでのWebAuthnセレモニー)、システムテスト(物理デバイスでのエンドツーエンド)。
必須のテストカテゴリ:
自動化戦略、プラットフォーム固有の注意点、および完全な飛行前チェックリストを含む包括的なテストガイダンスについては、専用ガイドを参照してください:ネイティブiOSおよびAndroidアプリでのパスキーフローのテスト。
従来のログイン(パスワード、OAuth)が成功した後に、ユーザーにパスキーの作成を促すことを検討してください。この段階的な変換アプローチは:
例: System WebViewを介したOAuthログイン後、ネイティブプロンプトを表示:「Face IDでより速くログインしますか?」承認された場合、System WebViewで読み込まれたウェブページを介してパスキーを作成します。
パスキーをネイティブ実装、System WebView、またはEmbedded WebViewのいずれで実装するかを決定することは、セキュリティ、ユーザー体験、開発の複雑さに影響を与える重要な設計上の選択です。万能の答えはありません。
OAuthベースのアプリの場合: System WebView(ASWebAuthenticationSession、Chrome Custom Tabs)が推奨される出発点です。優れたOAuthサポート、最小限の実装工数、および自動的な認証情報共有を提供します。
ネイティブファーストのアプリの場合: できるだけ早くネイティブに移行しましょう。ネイティブのパスキーログインは、preferImmediatelyAvailableCredentialsのような独自の機能を備えた最もシームレスなUXを提供します。これにより、アプリ起動時に自動的にパスキーオーバーレイが表示されます。これはWebView実装では提供できません。iOSとAndroidがパスキーの第一級サポートを提供するようになった今、実際の成功事例は高い採用率を示しています。ツール(オープンソースのSDKやプラットフォームライブラリを含む)も成熟し、妥当な期間でネイティブ統合が達成可能になりました。デバイス管理ポリシー、クロスデバイス同期、サードパーティプロバイダに注意を払う必要がありますが、これらの課題は慎重なエンジニアリングとテストで管理できます。その結果、ユーザーをその簡単さと速さで喜ばせ、セキュリティを大幅に向上させるアプリログインが実現します。
Embedded WebViewのフレーム要件の場合: Embedded WebViewは、2つの実際のシナリオで一般的に使用されます。第一に、OAuthベースのアプリは、最初のログインフローにSystem WebViewを使用し、その後、セッション制御が必要な設定画面でパスキー管理オプションをレンダリングするためにEmbedded WebViewに切り替えることがよくあります。ただし、一部のアプリは両方のフローにSystem WebViewを使い続けることでこれを簡素化しています。第二に、パスキーを採用する前に既にWebViewフレームに認証フローを埋め込んでいたアプリは、一貫性のためにこのパターンを継続します。ネイティブWebAuthnサポートを備えたEmbedded WebView(AndroidX WebKit 1.12.1+)は、設定とセットアップ(権限、エンタイトルメント、WebView設定)が必要ですが、もはやカスタムのJavaScriptブリッジコードは必要ありません。Conditional UIはEmbedded WebViewではサポートされていないことに注意してください。既存の埋め込み認証パターンを維持する場合や、認証後の画面でセッション/Cookie制御が必要な場合にこのアプローチを選択してください。
最終的に、ネイティブアプリのパスキーは、ユーザーの利便性とセキュリティの両方において大きな飛躍を意味します。ネイティブ、System WebView、またはEmbedded WebViewのいずれを介して実装されても、フィッシングのリスクやパスワード管理の負担をユーザーから取り除きます。VicRoadsのネイティブアプリパスキー統合のような実際の導入事例は、自動パスキーオーバーレイのような機能で適切に実行された場合、ネイティブファーストのアプローチが最高のユーザー採用率と満足度をもたらすことを示しています。ユーザーフレンドリーな認証のベストプラクティスに従い、アプリのアーキテクチャに合った実装アプローチ(新しいアプリにはネイティブファースト、OAuthフローにはSystem WebView、既存の埋め込みパターンにはEmbedded WebView)を選択することで、パスキーのビジョンである、誰にとってもシンプルで安全、そして快適な認証を真に実現するパスワードレスの生体認証ログインを提供できます。
ネイティブアプリでパスキーが機能しない場合は、実装アプローチごとにこれらの一般的な問題を確認してください。
application/json.well-knownパスにリダイレクトがないかhttps://your-domain.com(app://ではない)webcredentials:yourdomain.comで有効になっているかASWebAuthenticationSession(推奨)またはSFSafariViewControllerを使用しているか?mode=developerでテストする(本番では削除)WebViewFeature.WEB_AUTHENTICATIONのランタイム機能チェックsetWebAuthenticationSupport()がWEB_AUTHENTICATION_SUPPORT_FOR_APPで呼び出されているか"NotAllowedError: The request is not allowed by the user agent or the platform in the current context"
setWebAuthenticationSupport()の呼び出しパスキーのプロンプトが表示されない
?mode=developerを使用、WebViewタイプの確認詳細なデバッグについては、ネイティブアプリにおけるRelying Party IDに関する記事を参照してください。
Corbado ネイティブSDK:
プラットフォームドキュメント:
検証ツール:
Passkeys Series: Native Apps
Related Articles
Passkey Tutorial: How to Implement Passkeys in Web Apps
Vincent - December 7, 2023
The High-Level Architecture of an Integrated Passkey Flow
Janina - December 21, 2022
Table of Contents