Get your free and exclusive +90-page Banking Passkey Report
Back to Overview

原生应用 Passkey:原生实现与 WebView 实现对比

本文讲解如何在原生应用(iOS + Android)中实现 Passkey。您将了解到哪种类型的 WebView 最适合用于 Passkey 认证。

Vincent Delitz

Vincent

Created: June 20, 2025

Updated: December 10, 2025

native app passkeys

See the original blog version in English here.

WhitepaperEnterprise Icon

+70-page Enterprise Passkey Whitepaper:
Learn how leaders get +80% passkey adoption. Trusted by Rakuten, Klarna & Oracle

Get free Whitepaper

原生应用 Passkey 实现方式速查表#

方法采用率创建 Passkey使用 Passkey管理 Passkey技术复杂度OAuth 支持
原生实现🟢🟢🟢采用率高,最佳 UX,无缝生物识别即时、静默认证完全原生控制中-高需要独立流程
系统 WebView🟢🟢采用率良好,类似浏览器的体验标准浏览器 UX,共享密钥链基于浏览器的管理极佳
嵌入式 WebView🟢采用率较低,需要更多设置iOS 和 Android 原生支持(WebKit 1.12.1+),无 Conditional UI有限的控制中-高不适用

注意: 系统 WebView 和嵌入式 WebView 常常结合使用。系统 WebView 负责处理登录(自动共享凭据),然后嵌入式 WebView 在设置中渲染 Passkey 管理界面。

关键决策因素:

  • 是否基于 OAuth 登录? → 系统 WebView(ASWebAuthenticationSession、Chrome Custom Tabs)
  • 想在原生外壳中复用网页端认证? → 嵌入式 WebView(WKWebView,使用 WebKit 1.12.1+ 的 Android WebView)
  • 正在构建原生优先的应用? → 原生实现(Apple AuthenticationServices、Google Credential Manager)

1. 原生应用 Passkey 实现方案的选择#

现代移动平台为原生应用提供了三种不同的 Passkey 集成方法,每种方法在用户体验、技术复杂度和 OAuth 兼容性方面都有不同的权衡:

  1. 原生实现:使用平台 API(iOS 的 AuthenticationServices,Android 的 Credential Manager)直接在应用中构建 Passkey 流程。这种方法能提供最佳的用户体验,实现无缝的生物识别认证,但技术实现工作量为中到高。

  2. 系统 WebView:使用平台的浏览器组件(iOS 的 ASWebAuthenticationSession / SFSafariViewController,Android 的 Chrome Custom Tabs)来处理认证。这种方法非常适合基于 OAuth 的登录流程,并能与系统浏览器共享凭据。

  3. 嵌入式 WebView:在应用内嵌入一个可定制的网页视图(iOS 的 WKWebView,Android 的 WebView),以便在原生应用骨架中复用网页认证。它能提供类似原生的外观,没有 URL 地址栏,并且可以完全控制 WebView 的 UI。但这需要额外的设置,包括权限和授权(iOS),以及使用 AndroidX WebKit 1.12.1+ 配置 WebView(Android),才能启用 Passkey 功能。

正确的选择取决于您应用的认证架构、是否使用 OAuth 提供商、对 UI 的控制需求,以及您是在构建原生优先的应用还是在复用网页组件。

1.1 原生实现:最佳用户体验#

原生 Passkey 实现能提供最优的用户体验,认证流程使用平台特定的 API 直接构建在应用 UI 中。用户可以享受到平台原生的对话框、无缝的生物识别验证和最快的登录速度。

何时选择原生实现:

  • 构建新的原生应用或将认证重构为原生界面
  • 想要提供最佳用户体验,实现即时、静默的认证
  • 应用启动时自动提示 Passkey:原生实现可以使用 preferImmediatelyAvailableCredentials 在有可用 Passkey 时自动显示 Passkey 浮层,无需输入标识符,提供最快的登录体验
  • 需要完全控制认证 UI 和流程
  • 愿意投入资源进行平台特定的实现(iOS Swift、Android Kotlin)

关键优势:preferImmediatelyAvailableCredentials()

原生实现可以利用 preferImmediatelyAvailableCredentials() 创建一个自动 Passkey 浮层,当有可用 Passkey 时,这个浮层会在应用启动时立即出现。这种无用户名的流程提供了最快的登录体验——用户无需先输入标识符就能立即看到他们的 Passkey。这个功能是原生实现独有的,在 WebView 方案中无法使用。

虽然 WebView 实现可以使用 Conditional UI(在输入框中提供 Passkey 建议),但原生实现的自动浮层提供了更优的 UX,因为认证在应用启动时就立即开始,从而带来更高的 Passkey 使用率。

技术要求概述:

原生 Passkey 集成要求您的应用和 Web 域之间建立加密信任关系。否则,操作系统将拒绝所有 WebAuthn 操作。关键要求包括:

  1. 托管在 /.well-known/ 下的应用-域关联文件
  2. 与您的 Web 域匹配的正确的 Relying Party ID
  3. 平台特定的能力(详见第 4 节)

主要的好处是:在您的网站上创建的 Passkey 可以在您的应用中无缝使用,反之亦然。

1.1.1 在 iOS (Swift) 上实现原生 Passkey#

iOS 上原生实现 Passkey 需要使用苹果的 AuthenticationServices 框架,该框架为 WebAuthn 操作提供了 API:

关键组件:

  • ASAuthorizationController:管理认证流程
  • ASAuthorizationPlatformPublicKeyCredentialProvider:创建 Passkey 请求
  • 三种不同的 UI 模式来处理 Passkey 登录:
    • 文本框登录:传统的用户名输入框,点击按钮后开始Passkey 登录
    • Passkey 模态浮层:列出可用 Passkey 的操作系统对话框
    • Conditional UI:键盘上方的 QuickType 栏中显示 Passkey 建议

开发技巧

  • AASA 缓存:苹果会积极地缓存 AASA 文件(长达 24 小时),这可能会给测试带来麻烦。解决方案:在测试设备上启用开发者模式,并在 AASA URL 后附加 ?mode=developer 以强制刷新。
  • 性能测试:使用包含数百个凭据的 iCloud 账户进行测试,以观察真实场景下的延迟。当存储了大量 Passkey 时,系统浮层可能会显示轻微的延迟。

1.1.2 在 Android (Kotlin) 上实现原生 Passkey#

Android 的原生 Passkey 实现使用 Credential Manager API(或旧版的 FIDO2 API 以实现向后兼容):

关键组件:

  • CredentialManager:所有凭据操作的中心 API
  • CreatePublicKeyCredentialRequest:用于 Passkey 注册
  • GetCredentialRequest:用于 Passkey 认证
  • 两种主要的 UI 模式:
    • 文本框登录:传统的用户名输入框,点击按钮后开始 Passkey 登录
    • Passkey 模态浮层:列出可用 Passkey 的操作系统对话框

注意:Android 目前在原生应用中缺少像 iOS 那样的 Conditional UI 键盘建议(尽管 Conditional UI 在 Web 应用中是可用的)。

1.1.3 实现中的挑战与解决方案#

原生实现 Passkey 会遇到一些重要的挑战和经验教训:在操作系统层面进行集成,可能会暴露出不同设备和操作系统版本之间的问题。

  1. 例如,我们的团队曾遇到过苹果对 apple-app-site-association 文件(用于应用/网站凭据链接)的激进缓存问题,以及某些 Android OEM 厂商在生物识别提示 UI 上的细微差异。
  2. 此外,需要考虑到在某些企业场景中,受管设备可能会根据策略禁用 Passkey 同步。在 iCloud KeychainGoogle Password Manager 同步被关闭的公司环境中,Passkey 会绑定到特定设备而无法漫游——这是一个需要提前规划的重要场景(例如,确保用户在换新手机后仍能登录)。
  3. 另外,第三方凭据管理器应用也会影响流程。例如,如果用户将像 1Password 这样的密码管理器设置为活动的凭据提供者,它通常会拦截 Passkey 创建和存储,优先级高于平台的原生凭据管理器。

1.1.4 使用原生 SDK 简化开发#

虽然您可以使用原始的平台 API 来实现 Passkey,但专用的 SDK 能通过处理 WebAuthn 的复杂性、边缘情况并提供内置的遥测数据,从而显著加快开发速度。SDK 还为单元测试提供了可模拟的接口(这至关重要,因为您无法在模拟器中测试生物识别)。

建议: 对于原生实现,我们推荐使用 Corbado SDK(iOS Swift Passkey SDKAndroid Kotlin Passkey SDK),它们处理了在生产部署中发现的大量边缘案例,并提供了额外的遥测和测试功能。

Igor Gjorgjioski Testimonial

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.

快速实现数百万用户采用的 Passkey。从 Corbado 的采用平台开始。

开始免费试用

1.2 系统 WebView 实现:对 OAuth 友好的认证#

系统 WebView 使用平台的原生浏览器组件来处理应用内的认证。与完全原生的实现不同,系统 WebView 使用实际的系统浏览器(iOS 上的 Safari,Android 上的 Chrome)来显示网页内容,从而保留了共享的 cookie、已保存的凭据以及用户熟悉的浏览器安全指示器。

何时选择系统 WebView:

  • 您的应用使用基于 OAuth 的登录:系统 WebView 是 OAuth2/OIDC 流程的推荐方法,能提供安全的认证。
  • 希望在移动应用中复用现有的基于 Web 的认证。
  • 需要支持多种认证方法(密码、社交登录、Passkey),而不想重新构建原生界面。
  • 希望在 Web 和移动端之间维护一套统一的认证代码库。

主要优势:

  • OAuth 兼容性:专为 OAuth/OIDC 认证流程打造。
  • 安全指示器:用户可以看到真实的 URL 和 SSL 证书,从而建立信任。
  • 实现工作量低:仅需少量原生代码。
  • 一致的 UX:用户熟悉且信任的浏览器界面。

平台组件:

  • iOSASWebAuthenticationSession(推荐用于认证流程)或 SFSafariViewController(用于通用浏览)。
  • Android:Chrome Custom Tabs (CCT)。

像 Google 和 GitHub 这样的大公司都采用了这种方法,通过在现有的 Web 认证页面上叠加 WebView,为其移动应用添加 Passkey 登录功能。当无法立即进行完全原生的认证重构时,这种方法非常有效。

1.2.1 iOS 系统 WebView 选项#

iOS 为认证提供了两种主要的系统 WebView 组件:

ASWebAuthenticationSession(推荐用于认证):

  • 专为 OAuth/OIDC 和安全登录流程设计。
  • 自动提示用户应用想要进行认证。
  • 与 Safari 共享 cookie 和凭据。
  • 通过 iCloud Keychain 支持 Passkey。

SFSafariViewController(通用浏览):

  • 在应用内提供完整的 Safari 体验。
  • 显示 URL 栏和安全指示器。
  • 在 iOS 11+ 上不共享 Safari cookie;如果需要共享 Safari 会话,请使用 ASWebAuthenticationSession
  • 可定制性较低,但对用户来说更值得信赖。
功能ASWebAuthenticationSessionSFSafariViewController
主要用例认证流程通用网页浏览
OAuth/OIDC极佳良好
Passkey 支持
定制化有限极少

如果您的应用使用基于 OAuth 的登录,推荐选择 ASWebAuthenticationSession,因为它专为认证场景设计,并能在安全性和用户体验之间取得最佳平衡。

1.2.2 Android 系统 WebView:Chrome Custom Tabs#

Chrome Custom Tabs (CCT) 在您的应用内提供由 Chrome 驱动的认证体验:

主要特性:

  • 与 Chrome 浏览器共享 cookie 和凭据。
  • 显示 URL 和安全指示器。
  • 可定制工具栏颜色和品牌标识。
  • 支持预热以加快加载时间。

OAuth 集成:Chrome Custom Tabs 是 iOS ASWebAuthenticationSession 在 Android 上的等价物,提供出色的 OAuth 支持,同时保留对已存储 Passkey 的访问权限。

Demo Icon

Want to try passkeys yourself in a passkeys demo?

Try Passkeys

1.3 嵌入式 WebView 实现:需要额外设置的会话控制#

嵌入式 WebView 让您可以完全控制应用内网页内容的渲染,允许直接操作 cookie、会话和导航,且不显示 URL 栏。然而,这种控制权需要额外的技术配置才能启用 Passkey 功能。

何时选择嵌入式 WebView:

  • 追求类似原生的体验:您的应用已经在一个定制的 WebView 中嵌入了认证流程,以保持原生的外观和感觉,并且您希望保持这种一致的用户体验。
  • 需要会话/cookie 控制:您的应用需要在 OAuth 认证完成后直接操作认证令牌和会话状态。
  • 现有认证流程中,系统 WebView 认证返回了授权码,但在嵌入式上下文中没有会话。
  • 必须在多个嵌入式 Web 屏幕之间保持认证状态。
  • 仅限第一方认证:您的应用直接处理认证,关于第三方 Passkey 实现,请参见此处
  • 使用 AndroidX WebKit 1.12.1+ 并进行运行时功能检测。
  • 接受登录时 Conditional UI 的限制(嵌入式 WebView 不支持),但这与管理设置无关。

重要背景:

许多应用采用混合方法:使用系统 WebView 处理初始的 OAuth 认证(Passkey 在此能无缝工作),然后在认证后切换到嵌入式 WebView,以便在设置中管理 Passkey。挑战在于尝试直接在嵌入式 WebView 中使用 Passkey。

技术要求:

与系统 WebView 相比,嵌入式 WebView 需要额外的设置:

  1. iOS:关联域(Associated Domains)授权、AASA 文件配置。
  2. Android:AndroidX WebKit 1.12.1+ 以及 WebView WebAuthn 配置(需要功能检测)。
  3. 两者都需要:正确配置的 well-known 关联文件和 Digital Asset Links。

平台组件:

  • iOSWKWebView
  • Androidandroid.webkit.WebView

权衡:

  • 中等复杂度:需要 WebView 配置(Android WebKit 1.12.1+)和授权设置(iOS)。
  • Passkey 采用率较低:与原生实现相比,用户可能会遇到更多障碍。
  • 不支持 Conditional UI:输入框中的Passkey 自动填充在 Android 嵌入式 WebView 中不起作用。
  • 有限的平台支持:某些功能可能无法稳定工作(例如自动创建 Passkey)。

2. WebView 选项概述#

当通过 WebView 实现 Passkey 时,理解系统 WebView 和嵌入式 WebView 之间的区别至关重要。上面概述的三种方法(原生实现、系统 WebView 和嵌入式 WebView)各自服务于不同的用例。

在 iOS 上,您有多种在应用内显示 Web 内容的选项:

  • WKWebView 是一个可定制的 WebView 组件,属于 WebKit 框架(在 iOS 8 中引入)。它让您可以高度控制 Web 内容的外观和行为。
  • SFSafariViewController 是苹果提供的一个视图控制器,在您的应用内充当一个轻量级的 Safari 浏览器。它使用 Safari 的引擎。在 iOS 11+ 上,它有独立的 cookie 存储,不与 Safari 共享 cookie。如果需要共享 Safari 会话,请使用 ASWebAuthenticationSession。
  • SFAuthenticationSession / ASWebAuthenticationSession 是专门的 Web 认证会话(自 iOS 11/12 起可用),专门用于 OAuth/OpenID 或其他安全登录流程。它们也在底层利用 Safari,但专注于认证流程,并自动处理共享 cookie 和单点登录(SSO)等事宜。

在 Android 上,主要的选择是:

  • Android WebView 是标准的 WebView 控件(android.webkit.WebView),它本质上是一个可以嵌入到您的 Activity 中的迷你浏览器。它高度可定制,但在您的应用进程中运行。
  • Chrome Custom Tabs (CCT) 是一项功能,可在您的应用上下文中打开一个由 Chrome 驱动的标签页。Custom Tabs 看起来是您应用的一部分,但由 Chrome 浏览器(如果已安装)提供支持,具有预加载、共享 cookie 和用户熟悉的 URL 栏等功能,以增强用户信任

在接下来的部分中,我们将更深入地探讨 iOS 和 Android 的这些 WebView 类型,并讨论哪种最适合 Passkey 认证流程。

Substack Icon

Subscribe to our Passkeys Substack for the latest news.

Subscribe

3. iOS 中的 WebView#

苹果平台提供了上述三种 WebView 选项。您的选择将影响 Passkey 在应用内的使用流畅度:

要测试 iOS 中不同 WebView 的行为,我们推荐使用这款应用:WebView - WKWebView and UIWebView rendering

3.1 WKWebView#

WKWebView 是 iOS 的一个多功能 WebView 组件。开发者可以嵌入一个 WKWebView 来渲染 Web 内容,并对其 UI 和行为有很高的控制度。WKWebView 使用与 Safari 相同的渲染引擎,因此性能非常好,并支持现代 Web 功能。理论上,如果配置正确,WKWebView 可以处理 WebAuthn(从而支持 Passkey),但请注意,出于安全原因,某些高级浏览器功能可能会受到限制。需要注意的一点是,WKWebView 默认不与移动版 Safari 共享 cookie 或钥匙串数据。用户可能需要重新登录,因为他们的 WebView 会话与 Safari 的会话是隔离的。此外,由于 WKWebView 的内容可以由应用完全定制,用户看不到地址栏或 Safari UI——这对于品牌塑造来说很棒,但意味着用户几乎没有线索来验证页面的合法性(这是一个反钓鱼的担忧)。一些应用甚至滥用 WKWebView 来注入脚本或篡改内容(例如,TikTok 就被发现在其应用内浏览器中通过 WKWebView 注入跟踪 JS),因此必须谨慎使用 WKWebView,确保其安全且值得用户信赖。

3.2 SFSafariViewController#

SFSafariViewController 提供应用内的 Safari 体验。当您使用 SFSafariViewController 打开一个 URL 时,几乎就像在真正的 Safari 浏览器中打开它一样,只是用户仍然停留在您的应用 UI 内。这对 Passkey 的好处是显著的:因为它本质上是 Safari,所以用户的 iCloud Keychain 和已保存的 Passkey 都可以访问。请注意,在 iOS 11+ 上不共享 cookie。这意味着如果用户已经为您的网站创建了 Passkey,Safari 可以找到它,甚至显示 Conditional UI 自动完成功能以便轻松登录。SFSafariViewController 的可定制性较低(您不能大幅更改其工具栏),但它会自动处理许多安全和隐私功能。URL 栏会显示,并带有 HTTPS 的挂锁图标,这让用户确信他们访问的是正确的域名。总的来说,SFSafariViewController 被认为比原始的 WKWebView 更安全,并且实现起来更简单(苹果将其作为即插即用的组件提供)。主要的权衡是您牺牲了对外观和感觉的一些控制。对于认证流程来说,这通常是可以接受的。这里的优先事项是安全性和登录的便捷性,而 SFSafariViewController 通过使用 Safari 的上下文在这方面表现出色。

WKWebViewSFSafariViewController
用户体验- 原生感: 用户可能会觉得网页内容是应用的原生部分,因为开发者可以定制外观和感觉以匹配应用的设计。
- 自动填充: 可以使用来自 Safari 的数据进行自动填充。
- 无缝体验: 使用用户的 Safari 设置,确保原生应用和浏览器之间的网页浏览体验一致,提供无缝的用户体验。
开发者体验- 高度可定制: 提供广泛的定制和配置选项。
- 灵活: 提供许多用于与网页内容交互的 API。
- 中度可定制: 定制选项有限,特别是与 WKWebView 相比。
- 简单: 与 WKWebView 相比,实现更简单。
性能- 相对较慢: 根据实现和网页内容的不同,加载速度可以优化,但由于需要额外处理自定义功能和交互,可能仍比 SFSafariViewController 慢。- 相对较快: 通常性能更好,因为它利用了为速度和效率优化的 Safari 引擎,为网页提供了快速的加载时间。
信任与识别- 不要求显示 URL: WKWebView 通常不显示 URL,使用户更难验证网页。恶意应用可能会模仿这种行为并进行钓鱼攻击。- 类似浏览器的体验: 使用 Safari 渲染网页,提供“类似浏览器”的体验。用户可以看到 URL 并访问 Safari 的自动填充功能,熟悉的界面可能会带来更多信任。
隔离性- 分离: Cookie 和会话与 Safari 分离;用户不会在 WKWebView 中自动登录。- 分离: Cookie 和会话也与 Safari 分离;用户同样不会在 SFSafariViewController 中自动登录。
漏洞- 安全: 由于苹果的应用沙盒机制,本身是安全的,但其行为和安全性取决于应用的实现。如果实现不当,可能存在漏洞。- 更安全: 受益于 Safari 内置的安全功能,包括反钓鱼和恶意网站警告。由于这些功能和用户对 Safari 的熟悉度,通常认为它在显示网页内容方面比 WKWebView 更安全。
其他- 部分功能不可用: 由于安全问题和 WKWebView 在应用上下文中运行,某些浏览器功能(例如 WebAuthn)可能无法完全访问。
- JavaScript 注入: 一些应用,如 TikTok,会在其应用内的 WKWebView 中注入跟踪 JavaScript,或限制用户控制(如 Facebook)。
- 隐私问题: 有更多关于隐私的社区反馈
- 无 JavaScript 注入: 不允许应用执行 JavaScript,增强了安全性和隐私。它也不支持 JavaScript 警报或确认框,这可能会影响某些网页的用户体验。
- 阅读模式: 提供阅读模式,为文章提供干净、易于阅读的版本。

3.3 SFAuthenticationSession / ASWebAuthenticationSession#

SFAuthenticationSession / ASWebAuthenticationSession —— 这些类(后者是更新的、对 Swift 更友好的名称)是专门为像 OAuth 或 OpenID Connect 这样的登录流程构建的。当您需要通过网页对用户进行身份验证时(可能需要访问外部 IdP),这些会话是 iOS 上的推荐选择。它们与 SFSafariViewController 非常相似,因为它们在底层利用 Safari 浏览器并与 Safari 共享 cookie/存储。关键区别在于,SFAuthenticationSession 总是会提示用户应用希望使用网页进行身份验证(以提高用户意识),并且如果可用,它会自动使用用户现有的 Safari 会话。

这样做的好处是实现了无缝的 SSO 体验——如果用户已经在 Safari 中登录了提供商,此会话可以使用该 cookie 来避免再次登录。对于 Passkey 来说,这一点很重要,因为它意味着存储在 Safari/iCloud Keychain 中的任何 Passkey 凭据也可以在这里使用。苹果的官方指南建议对任何看起来像登录流程的操作都使用 ASWebAuthenticationSession。其优点是增强了隐私性(您的应用永远看不到凭据或 cookie,由 Safari 处理)和内置的 SSO 支持。缺点是它仅限于认证流程(您不会用它来在应用中渲染任意的网页内容)。总而言之,如果您在 iOS 上选择 WebView 方法,ASWebAuthenticationSession 通常是实现 Passkey 的最佳选择,因为它安全、与 Safari 共享状态,并且是为认证而专门设计的。

StateOfPasskeys Icon

Want to find out how many people use passkeys?

View Adoption Data

4. Android 中的 WebView#

在 Android 上,WebView 的决策是在经典的 WebView 和 Chrome Custom Tabs 之间选择:

要测试 Android 中不同 WebView 的行为,我们推荐使用这款应用:WebView vs Chrome Custom Tabs

4.1 Android WebView#

Android WebView (android.webkit.WebView) 是一个允许您在 Activity 布局中嵌入网页的组件。它与 WKWebView 类似,因为它给了您完全的控制权:您可以拦截导航、注入 JavaScript、定制 UI 等。它也在您的应用进程内运行。使用 WebView 实现 Passkey 意味着您的应用加载您的 Web 登录页面,该页面可以启动 WebAuthn Passkey 流程。现代的 Android WebView 支持 WebAuthn(前提是设备的 WebView 实现通过 Android System WebView 或 Chrome 组件保持最新)。一个主要考虑因素是:默认情况下,Android WebView 不与用户的 Chrome 浏览器共享 cookie 或存储的凭据。因此,在 WebView 中创建或使用的任何 Passkey 可能不为 Chrome 所知,反之亦然。这种隔离对安全有好处(您的应用无法读取浏览器 cookie),但如果用户已经在 Chrome 中进行了身份验证,这可能会迫使用户再次登录。另一个问题是信任。一个普通的 WebView 不会显示 URL 或 SSL 锁图标,所以用户必须完全信任您的应用不会对他们进行钓鱼攻击。由于潜在的钓鱼风险,Google 甚至禁止使用 WebView 进行 Google OAuth 登录。在性能方面,WebView 还可以,但它们可能比使用用户的默认浏览器更慢或更耗内存,尤其是在加载大型页面时。

4.2 Chrome Custom Tabs (CCT)#

Chrome Custom Tabs (CCT) 是一种混合方法。它们允许您的应用打开一个由 Chrome 渲染的页面,看起来就像是您应用的一部分。您可以定制工具栏颜色、添加应用徽标等,但内容由 Chrome 在一个单独的进程中渲染。对于 Passkey,CCT 有几个好处:它们与 Chrome 共享用户的 cookie 和凭据,这意味着如果用户通过 Chrome(Google 密码管理器)保存了 Passkey,Custom Tab 可以访问它。用户还会看到实际的 URL 和安全指示器,这有助于建立信任。性能通常更好——Chrome 可以在后台“预热”以加快加载速度。而且重要的是,安全性很强:因为它本质上是 Chrome 应用,所以像 Google Safe Browsing 这样的功能会保护会话,并且您的应用无法向页面注入任意脚本(防止某些攻击)。

缺点是它要求用户安装并更新 Chrome(或受支持的浏览器)。大多数 Android 用户都有,但在某些地区的一些设备上,这可能是一个问题。总的来说,如果您在 Android 上采用嵌入式 Web 方法,Chrome Custom Tabs 是 Passkey 流程的推荐选择,因为它们在集成和安全性之间取得了很好的平衡。实际上,它们在很多方面都类似于 iOS 的 SFSafariViewController/ASWebAuthSession——利用默认浏览器进行认证。

(旁注:苹果的 WKWebView vs SFSafariViewController 和 Android 的 WebView vs CCT 有许多相似之处。Safari VC 和 Chrome Tabs 都共享浏览器状态并提供更好的安全性,而 WKWebView/Android WebView 则提供更多控制权但隔离了 Web 内容。对于 Passkey,共享状态(cookie、凭据存储)通常是可取的,这样可以无缝地访问和创建 Passkey。)

功能WebViewChrome Custom Tab
用户体验- 灵活性: 提供丰富的 API 用于与网页内容交互和管理用户交互,包括处理 JavaScript 对话框和权限请求。
- 一致性: 保持一致的 UX,尤其是在处理各种网页内容时,可能具有挑战性。
- 浏览器功能: 共享数据节省和跨设备同步自动完成等功能。
- 返回按钮: 允许用户通过集成的返回按钮轻松返回应用。
- 依赖性: 依赖 Chrome 应用,该应用可能在所有用户设备上都不可用或未更新。
- 重定向到浏览器: 某些功能可能会将用户重定向到 Chrome 应用,可能中断用户体验。
- 部分 Custom Tabs: 只有屏幕的一部分可用于 Chrome Custom Tab,其余部分显示原生应用。
- 侧边栏: 在横屏模式和或大屏设备上,Chrome Custom Tab 仅显示在屏幕的一侧,其余部分显示原生应用。
开发者体验- 高度可定制: 提供广泛的定制选项/需求。
- 交互性: 提供众多 API 用于与网页内容交互和管理用户交互。
- 可定制: 允许定制工具栏颜色、操作按钮、底部工具栏、自定义菜单项以及进出动画。
- 回调: 在发生外部导航时向应用程序发送回调。
- 安全功能: 提供开箱即用的功能,无需管理请求、权限授予或 cookie 存储。
性能- 中等性能: 可能无法提供与 Chrome Custom Tabs (CCT) 相同的性能水平。- 预热: 包括在后台预热浏览器和推测性加载 URL,以缩短页面加载时间。
- 优先级: 通过将其重要性提升到“前台”级别,防止启动 Custom Tab 的应用在使用期间被系统回收。
信任与识别- URL 和 SSL 不可见: 在 WebView 中,URL 和 SSL 信息本身是不可见的。除非应用开发者实现这些功能,否则用户无法知道他们是在正确的网站上还是在钓鱼网站上。- URL 和 SSL 可见: 使用实际的 Chrome 浏览器渲染页面。用户可以看到 URL 和 SSL 证书(指示连接是否安全)。这可以给用户信心,让他们相信自己不在钓鱼网站上。
隔离性- 在应用的进程内运行: 如果应用存在允许恶意代码执行的漏洞,则存在 WebView 可能被攻破的风险。然而,WebView 也会收到更新,但其行为和安全性更依赖于使用它的应用。
- 无 Cookie/会话共享: 不与设备的主浏览器共享 cookie 或会话,提供了隔离性,但可能需要用户重新登录。
- 在 Chrome 的进程内运行: 作为 Chrome 的一部分,Custom Tabs 在同一进程中运行,并具有与 Chrome 相同的安全更新和功能。
- 共享的 Cookie Jar 和权限模型: 确保用户不必重新登录网站或重新授予权限。
- Chrome 设置与偏好: 利用 Chrome 的设置和偏好。
漏洞- 回调窃取凭据: 潜在漏洞包括有时需要 JavaScript,这为其他应用运行恶意代码打开了大门,例如注册试图拦截用户名和密码的回调
- 钓鱼: 此外,恶意应用可能会打开一个模仿 Link 流程的另一个网页,以进行钓鱼攻击。
- Google 安全浏览: 采用 Google 的安全浏览功能,保护用户和设备免受危险网站的侵害。
- 安全的浏览器装饰: 确保用户始终能看到他们正在交互的确切 URL,并可以查看网站的证书信息,从而降低钓鱼风险。此外,Custom Tabs 不允许 JavaScript 注入。
其他- Google 禁止使用 WebView 让用户登录 Google 账户。

5. 技术设置要求#

无论您选择哪种实现方法,都必须满足某些技术要求才能启用 Passkey 功能。本节提供了有关配置 well-known 关联文件、iOS entitlements 和 Android WebView 配置的全面指南。

关于受管设备的说明: 在受移动设备管理(MDM)策略控制凭据存储的受管设备上,Passkey 的行为会有显著不同。有关在受管设备上测试 Passkey 的信息,请参阅在受管 iOS 和 Android 设备上测试 Passkey

5.1 Well-Known 关联文件(原生和嵌入式)#

原生和嵌入式 WebView 流程需要关联文件来在您的应用和 Web 域之间建立加密信任。系统 WebView(ASWebAuthenticationSession)和 Chrome Custom Tabs 不需要应用到站点的关联。

5.1.1 iOS: Apple-App-Site-Association (AASA) 文件#

AASA 文件建立了您的 iOS 应用和您的 Web 域之间的连接,使 Passkey 能够跨两个平台工作。

文件位置https://yourdomain.com/.well-known/apple-app-site-association

配置要求

  • 托管在您域名的 /.well-known/apple-app-site-association 路径下。
  • 通过 HTTPS 提供服务,并使用有效的 SSL 证书。
  • Content-Type:application/json
  • .well-known 路径上无重定向。
  • 包含您应用的 Team ID 和 Bundle ID。

AASA 文件示例

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

AASA 缓存和测试

苹果会积极地缓存 AASA 文件(长达 24-48 小时),这可能会给开发和测试带来麻烦。要在开发期间绕过缓存:

  1. 在您的测试设备上启用开发者模式。
  2. 在 Xcode 中为您的关联域附加 ?mode=developer
  3. 这将强制 iOS 直接从您的服务器获取最新的 AASA 文件。

⚠️ 重要提示:不要在生产版本中使用 ?mode=developer。此参数仅用于开发——在生产环境中使用它会阻止 iOS 正确检测您的 AASA 文件,从而破坏 Passkey 功能。

验证:使用苹果的 AASA 验证器来验证您的配置。

Android 使用 Digital Asset Links 来验证您的应用和网站之间的关系。

文件位置https://yourdomain.com/.well-known/assetlinks.json

配置要求

  • 托管在您域名的 /.well-known/assetlinks.json 路径下。
  • 通过 HTTPS 提供服务,并使用有效的证书。
  • Content-Type:application/json
  • 包含您应用的 SHA256 指纹(来自签名证书)。

assetlinks.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 生成器来创建和验证您的配置。

5.2 iOS Entitlements 配置#

iOS 应用需要适当的授权才能访问 Passkey 功能。根据您的实现方法,要求略有不同。

5.2.1 理解 Runner.entitlements / YourApp.entitlements#

授权文件(在 Flutter 应用中通常命名为 Runner.entitlements,在原生 iOS 项目中为 YourApp.entitlements)定义了苹果系统授予的特殊权限和能力。对于 Passkey,此文件配置了关联域(Associated Domains)。

文件位置:通常在您的 Xcode 项目的 ios/Runner/Runner.entitlements 中。

5.2.2 关联域能力#

原生实现和嵌入式 WebView 需要关联域能力来将您的应用与您的 Web 域链接起来。系统 WebView (ASWebAuthenticationSession) 不需要此项,因为它在 Safari 的上下文中运行。

在 Xcode 中设置

  1. 在 Xcode 中打开您的项目。
  2. 选择您的应用目标。
  3. 转到“Signing & Capabilities”选项卡。
  4. 点击“+ Capability”并添加“Associated Domains”。
  5. 添加您的域名,并加上 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>

5.2.3 按方法区分的要求#

方法是否需要关联域额外配置
原生实现专门的实现
系统 WebView不需要默认的网页设置即可
嵌入式 WebView需要 AndroidX WebKit 1.12.1+ 配置

多个域:如果您的应用需要与多个域协同工作,您可能需要相关源请求 (ROR)

5.3 Android WebView 配置(仅限嵌入式 WebView)#

Android 嵌入式 WebView 在 AndroidX WebKit 1.12 中获得了原生的 WebAuthn 支持,从而不再需要自定义的 JavaScript 桥接代码。系统 WebView(Chrome Custom Tabs)不需要任何配置——凭据会自动工作。

5.3.1 原生 WebAuthn 支持(WebKit 1.12.1+,推荐)#

要求

  • AndroidX WebKit 1.12.1 或更高版本(推荐 1.14.0+)。
  • 配置了 Digital Asset Links。
  • 带有 WebAuthn 支持的 WebView APK(通过功能检测检查)。
  • 注意:WebView 的 WebAuthn 不需要 AndroidX Credentials 库,该库仅用于完全原生的实现。

实现

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 桥接:WebAuthn 在 WebView 中原生工作。
  • 需要功能检测:始终在运行时检查 WebViewFeature.WEB_AUTHENTICATION
  • 不支持 Conditional UImediation:"conditional"(输入字段中的 Passkey 自动填充)在嵌入式 WebView 中不起作用。
  • 回退策略:如果功能不可用,则改用 Chrome Custom Tabs。

版本说明

  • 使用 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 支持。团队必须选择:

  1. 使用 Chrome Custom Tabs 或 Auth Tab(推荐)。
  2. 构建一个自定义的 JavaScript 桥接。

如果您需要支持较旧的 Android 版本或没有更新 WebView APK 的设备,请参阅 Android 的 Credential Manager WebView 集成指南了解桥接代码方法。但是,我们强烈建议现代应用使用原生的 WebKit 1.12.1+ 方法

建议:使用 AndroidX WebKit 1.12.1+ 的原生 WebAuthn 支持。如果运行时不可用,则回退到 Chrome Custom Tabs,它提供了出色的 Passkey 支持和共享凭据。

5.4 源、相关源 (ROR) 和验证 Well-Known 文件#

在原生应用中实现 Passkey 时,您需要在您的应用和一个或多个 Web 域之间建立信任。本节介绍如何处理单个域、多个相关域(ROR)以及如何验证您的 well-known 关联文件是否配置正确。

5.4.1 单域设置#

对于使用单个域的应用(例如 kayak.com),您需要:

5.4.2 多个域的相关源 (ROR)#

相关源 (ROR) 是 WebAuthn 的一项功能,允许一组 Passkey 在多个相关域(例如 kayak.comkayak.dekayak.co.uk)之间工作。ROR 使用每个站点上的 /.well-known/webauthn 端点来定义相关源,而不是使用 AASA 或 assetlinks 文件。

关键点

  • ROR 配置:每个域都托管一个 /.well-known/webauthn 文件,其中包含相关源的列表。
  • 应用关联文件(AASA/assetlinks):仅用于将应用映射到其对应的网站。
  • iOS 18+ 嵌入式 WebView:在正确配置后支持 ROR。
  • 关联域授权:包含您的应用需要进行身份验证的所有域。

配置示例

如果您的应用与 kayak.comkayak.de 协同工作,那么这两个域都必须:

  • 托管各自的 AASA 文件,且具有相同的 Team ID 和 Bundle ID。
  • 在您应用的关联域授权中列出。
  • 拥有正确配置且可访问的 well-known 文件。

5.4.3 验证 Well-Known 文件#

在上线之前,请验证您的 well-known 文件是否配置正确且可访问。苹果和谷歌提供了基于 CDN 的测试 URL 来检查文件的可用性:

域名苹果 AASA 验证谷歌 Digital Asset Links 验证
kayak.com测试 AASA 文件
检查苹果 CDN 是否能检索到您的文件
测试 assetlinks.json
验证谷歌是否能访问您的 asset links
kayak.de测试 AASA 文件
检查苹果 CDN 是否能检索到您的文件
测试 assetlinks.json
验证谷歌是否能访问您的 asset links

使用这些测试 URL

  • 点击链接以验证苹果/谷歌是否可以检索到您的 well-known 文件。
  • 苹果的 ?nocache=1 参数会强制刷新,绕过 CDN 缓存。
  • 如果通过这些 URL 无法访问文件,那么您应用中的 Passkey 功能将无法工作。
  • 在上述 URL 模式中,将 kayak.comkayak.de 替换为您自己的域名。

测试注意事项:确保所有域都正确配置了 well-known 文件。任何一个域上的文件缺失或配置错误都可能导致该域的 Passkey 功能中断。

更多信息原生应用中的 WebAuthn Relying Party ID

6. 原生应用中 Passkey 实现的建议#

选择正确的实现方法取决于您应用的认证架构、OAuth 要求以及对会话控制的需求。使用此决策树来确定最佳路径。

6.1 决策树#

从以下关键问题开始:

  1. 您的应用是否使用基于 OAuth 的登录(OAuth2、OIDC、社交登录提供商)?

    • 系统 WebView(第 1.2 节)
      • iOS:使用 ASWebAuthenticationSession
      • Android:使用 Chrome Custom Tabs
      • 对 OAuth 的支持极佳,并共享凭据
  2. 您想在一个类似原生的外壳中复用网页认证(无 URL 栏,完全 UI 控制)吗?

    • 带配置的嵌入式 WebView(第 1.3 节)
    • iOS:WKWebView + 关联域授权
    • Android:WebView + AndroidX WebKit 1.12.1+ 配置
    • 在复用网页组件的同时提供类似原生的外观
    • 注意:嵌入式 WebView 不支持 Conditional UI
    • → 考虑系统 WebView 或原生实现
  3. 您是在构建新的原生应用还是已有原生登录界面?

    • 原生实现(第 1.1 节)
      • 最佳用户体验
      • 即时、静默认证
      • 需要平台特定的开发
  4. 您有想要复用的现有网页认证吗?

    • 系统 WebView 以快速实现
    • 原生实现 以获得最佳 UX

6.2 方法比较:采用维度#

以下是每种方法在关键维度上的表现:

方法创建 Passkey使用 Passkey管理 Passkey技术复杂度OAuth 支持设置时间
原生实现高采用率
无缝生物识别,最佳 UX
即时、静默
preferImmediatelyAvailableCredentials 可在应用启动时自动显示浮层
完全原生控制
与应用设置集成
中-高
平台特定 API
需要独立的 OAuth 流程实现数周到数月
系统 WebView良好采用率
类似浏览器的体验,熟悉
标准浏览器 UX
输入框中的 Conditional UI,共享密钥链
基于浏览器
用户通过浏览器管理

极少的原生代码
极佳
专为 OAuth 设计
数天到数周
嵌入式 WebView较低采用率
需要配置
原生 WebAuthn 支持
WebKit 1.12.1+,无 Conditional UI
有限控制
无原生集成
中-高
WebView 配置 + 权限
需要配置1-2 周

维度解释

  • 创建 Passkey:用户通过此方法创建 Passkey 的难易程度。
  • 使用 Passkey:使用现有 Passkey 时的认证体验。
  • 管理 Passkey:用户如何查看、编辑或删除 Passkey
  • 技术复杂度:开发工作量和持续维护。
  • OAuth 支持:该方法处理 OAuth2/OIDC 认证流程的效果。
  • 设置时间:典型的实现时间线。

6.3 按场景的具体建议#

6.3.1 场景 A:基于 OAuth 的认证(最常见)#

推荐:系统 WebView

如果您的应用通过 OAuth2、OIDC 或社交登录提供商(Google、GitHub、Microsoft 等)进行认证,系统 WebView 是最佳选择:

  • iOSASWebAuthenticationSession 专为 OAuth 流程设计。
  • Android:Chrome Custom Tabs 提供无缝的 OAuth 集成。
  • 好处:极少的原生代码,自动共享凭据。
  • 实现:将 WebAuthn 添加到您的网页认证页面,然后通过系统 WebView 加载它。

示例:像 kayak.com 和 kayak.de 这样的旅游应用使用 OAuth 进行认证。系统 WebView 允许它们在保留现有 OAuth 基础设施的同时,通过其网页认证页面添加 Passkey 支持。

6.3.2 场景 B:需要会话控制的原生登录#

推荐:混合方法

使用系统 WebView 进行初始 OAuth 认证,然后使用嵌入式 WebView 处理认证后的会话:

  1. 初始认证:系统 WebView 处理 OAuth + Passkey 登录。
  2. 会话管理:切换到嵌入式 WebView 以显示需要 cookie/会话控制的认证后网页内容。
  3. 技术设置:配置系统和嵌入式 WebView 的要求——对于 Android,确保包含 AndroidX WebKit 1.12.1+(见第 5 节)。

何时使用:通过 OAuth 进行认证,但之后需要显示需要直接会话操作的认证后网页内容的应用。

6.3.3 场景 C:新的原生应用或原生优先#

推荐:原生实现

从头开始构建或已有原生屏幕?那就选择完全原生:

  • iOS:使用 AuthenticationServices 框架。
  • Android:使用 Credential Manager API。
  • 好处:最佳 UX,即时认证,完全控制。
  • 独特优势:使用 preferImmediatelyAvailableCredentials应用启动时显示自动 Passkey 浮层——这是原生实现独有的功能,可提供最高的转化率
  • SDK 推荐:使用 Corbado SDK(iOSAndroid)来加速开发,并处理经过生产环境测试的边缘情况。

对于新应用:强烈建议从第一天起就构建原生登录。这为您提供了最佳的 UX,并避免了未来从 WebView 到原生的迁移。

6.3.4 场景 D:已有基于 Web 登录的现有应用#

推荐:分阶段迁移

  • 第一阶段:系统 WebView Passkey - 将 Passkey 支持添加到现有 Web 登录中,通过系统 WebView(ASWebAuthenticationSession/Chrome Custom Tabs)加载。这是一个只需少量原生代码的快速胜利。
  • 第二阶段:原生拦截 - 在显示 WebView 之前 添加原生 Passkey 检查。示例:kayak.com 首先尝试原生 Passkey 认证,如果需要则回退到 WebView。这在保持向后兼容性的同时提供了快速的生物识别登录。
  • 第三阶段:完全原生 - 逐步为 Passkey 用户迁移到原生认证,保留 WebView 用于传统方法。

这种分阶段的方法允许增量改进,而不会干扰现有用户。

6.4 按方法区分的关键技术要求#

要求原生系统 WebView嵌入式 WebView
Well-known 文件 (AASA/assetlinks)需要不需要需要
iOS 关联域需要不需要需要
Android WebKit 库不适用不需要需要 (1.12.1+)
Relying Party ID必须与域名匹配必须与域名匹配必须与域名匹配

有关详细的配置说明,请参见第 5 节。

6.5 测试建议#

在原生应用中测试 Passkey 需要一个结构化的、多层次的方法。遵循测试金字塔:单元测试(隔离的逻辑)、集成测试(在模拟器/仿真器上进行 WebAuthn 流程)和系统测试(在物理设备上进行端到端测试)。

基本测试类别:

  • 核心流程:注册、认证、跨设备流程、Passkey 删除
  • 平台覆盖:iOS(原生)、Android(原生)、跨操作系统版本的网页浏览器
  • 域关联:验证 AASA 文件(iOS)和 Digital Asset Links(Android)是否可访问
  • 取消流程:测试用户在操作系统提示和生物识别屏幕上的取消操作
  • 错误处理:后端失败、网络超时、凭据不匹配
  • 边缘情况:屏幕锁定禁用、iCloud/Google 密码管理器禁用
  • OAuth 流程:完整的 OAuth + Passkey 集成端到端测试
  • 受管设备:MDM 控制的环境(见受管设备测试
  • 第三方管理器:与 1PasswordBitwardenDashlane 的兼容性
  • 跨设备认证二维码流程和混合传输测试
  • 嵌入式 WebView 特定:如果使用嵌入式 WebView,请验证 Android 上的 WebKit 1.12.1+ 配置
  • 生产监控:用于监控成功率、失败率和延迟的仪表板

有关全面的测试指南,包括自动化策略、平台特定的陷阱和完整的飞行前检查清单,请参阅我们的专门指南:在原生 iOS 和 Android 应用中测试 Passkey 流程

6.6 机会性注册策略#

考虑在用户成功进行传统登录(密码、OAuth)之后 提示他们创建 Passkey。这种渐进式转换方法:

  • 不会干扰现有的认证流程。
  • 如果用户拒绝,可以优雅地降级。
  • 随着时间的推移,在不强迫用户改变的情况下,增加 Passkey 采用率
  • 适用于所有三种实现方法。

示例:通过系统 WebView 进行 OAuth 登录后,显示一个原生提示:“想用面容 ID 更快地登录吗?”如果用户接受,则通过在系统 WebView 中加载的网页创建 Passkey。

7. 结论#

决定如何实现 Passkey——通过原生实现、系统 WebView 还是嵌入式 WebView——是一个关键的设计选择,它影响着安全性、用户体验和开发复杂度。没有一刀切的答案。

对于基于 OAuth 的应用:系统 WebView(ASWebAuthenticationSession、Chrome Custom Tabs)是推荐的起点。它提供了出色的 OAuth 支持,实现工作量最小,并能自动共享凭据。

对于原生优先的应用:尽早采用原生实现。原生 Passkey 登录能提供最无缝的 UX,并具备 preferImmediatelyAvailableCredentials 等独有功能,这使得应用启动时可以自动显示 Passkey 浮层——这是 WebView 实现无法提供的。随着 iOS 和 Android 现在为 Passkey 提供一流的支持,现实世界的成功案例表明,采用率很高。相关工具(包括开源 SDK 和平台库)已经成熟,使得在合理的时间范围内实现原生集成成为可能。虽然您必须注意设备管理策略、跨设备同步和第三方提供商,但这些挑战可以通过精心的工程设计和测试来管理。其结果是一个能以其简便和速度取悦用户的应用登录,同时显著提高安全性。

对于嵌入式 WebView 框架要求:嵌入式 WebView 通常用于两种现实场景。首先,基于 OAuth 的应用通常使用系统 WebView 进行初始登录流程,然后切换到嵌入式 WebView 在设置屏幕中渲染 Passkey 管理选项,因为那里需要会话控制——尽管一些应用通过在两个流程中都使用系统 WebView 来简化此过程。其次,那些在采用 Passkey 之前就已经在 WebView 框架中嵌入了认证流程的应用,为了保持一致性而继续使用这种模式。带有原生 WebAuthn 支持(AndroidX WebKit 1.12.1+)的嵌入式 WebView 需要配置和设置(权限、授权、WebView 设置),但不再需要自定义的 JavaScript 桥接代码。请注意,嵌入式 WebView 不支持 Conditional UI。当您需要维护现有的嵌入式认证模式或在认证后屏幕需要会话/cookie 控制时,选择此方法。

最终,原生应用中的 Passkey 代表了用户便利性和安全性的巨大飞跃。无论是通过原生、系统 WebView 还是嵌入式 WebView 实现,它们都为您的用户消除了钓鱼风险和密码管理的负担。像 VicRoads 的原生应用 Passkey 集成这样的现实世界实现表明,当正确执行并结合自动 Passkey 浮层等功能时,原生优先的方法能带来最高的用户采用率和满意度。遵循用户友好认证的最佳实践并选择与您应用架构相匹配的实现方法——新应用选择原生优先,OAuth 流程选择系统 WebView,或现有嵌入式模式选择嵌入式 WebView——您就可以提供无密码的生物识别登录,真正实现 Passkey 的愿景:为每个人提供简单、安全和愉快的认证体验。

8. 故障排除清单#

如果 Passkey 在您的原生应用中不起作用,请按实现方法检查以下常见问题:

所有方法:关联文件问题#

  • 文件通过 HTTPS 提供,并带有有效证书
  • 正确的 MIME 类型:application/json
  • .well-known 路径上没有重定向
  • iOS:AASA 文件中的 Team ID 和 Bundle ID 完全匹配
  • Android:assetlinks.json 中的 SHA256 指纹与您的签名证书匹配
  • Relying Party ID 与您的域名匹配(无协议,无端口)
  • RP ID 中没有尾部斜杠
  • WebAuthn origin: https://your-domain.com (而不是 app://)

原生实现#

  • iOS:在 Xcode 中启用了关联域能力,并配置了 webcredentials:yourdomain.com
  • Android:在 AndroidManifest.xml 中声明了 Digital Asset Links
  • 用户已启用屏幕锁定(生物识别或 PIN)
  • 使用苹果的 AASA 验证器和谷歌的 Digital Asset Links 工具进行测试
  • 验证 Runner.entitlements 文件包含正确的关联域

系统 WebView#

  • iOS:正在使用 ASWebAuthenticationSession(推荐)或 SFSafariViewController
  • Android:正在使用 Chrome Custom Tabs(而不是普通的 WebView)
  • iOS:如果需要,验证关联域已配置
  • 测试 cookie/凭据是否与系统浏览器共享
  • 验证网页认证页面有正确的 WebAuthn 实现

嵌入式 WebView#

  • iOS:配置了正确的授权
  • iOS:关联域包含所有相关域名
  • 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 功能(使用功能检测,而非操作系统版本)
  • 未使用 Conditional UI(在嵌入式 WebView 中不受支持)
  • 如果 WebAuthn 功能不可用,则回退到 Chrome Custom Tabs

第三方提供商问题#

  • 检查用户是否激活了非默认的凭据提供商(1PasswordBitwarden 等)
  • 验证提供商是否支持 Passkey(并非所有密码管理器都支持)
  • 使用平台原生的凭据管理器进行测试(iCloud Keychain、Google Password Manager

常见错误信息#

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

  • 通常意味着:缺少授权(iOS)或 WebView 功能不可用/未启用(Android 嵌入式 WebView)
  • 检查:关联域配置、AASA 文件可访问性、WebKit 版本、功能检测、setWebAuthenticationSupport() 调用

没有出现 Passkey 提示

  • 可能意味着:AASA/assetlinks.json 未加载、WebView 类型错误、AASA 文件被缓存
  • 尝试:验证关联文件、在 iOS 上使用 ?mode=developer 进行测试、验证 WebView 类型

有关详细的调试信息,请参阅我们关于原生应用中 Relying Party ID 的文章

9. 资源#

Corbado 原生 SDK:

平台文档:

验证工具:

Add passkeys to your app in <1 hour with our UI components, SDKs & guides.

Start Free Trial

Share this article


LinkedInTwitterFacebook