本文讲解如何在原生应用(iOS + Android)中实现 Passkey。您将了解到哪种类型的 WebView 最适合用于 Passkey 认证。
Vincent
Created: June 20, 2025
Updated: June 24, 2025
Our mission is to make the Internet a safer place, and the new login standard passkeys provides a superior solution to achieve that. That's why we want to help you understand passkeys and its characteristics better.
认证是保护用户数据、确保原生应用内安全交互的哨兵。Passkey 的出现彻底改变了这一领域,提供了一种强大且用户友好的认证机制。将 Passkey 集成到原生应用主要有两种方式:通过原生实现或通过 WebView。让我们先来看看这两种方式的比较。
原生实现通常被认为能在应用内提供最佳的用户体验。其特点是流畅、集成和一致的用户交互,完全针对操作系统环境(无论是 iOS 还是 Android)量身定制。实现 100% 原生需要做到 100% 无密码,并真正实现 Passkey 原生。这种方法使您摆脱了在原生应用和(通过 WebView 显示的)Web 内容之间切换时可能产生的摩擦。
在开发原生应用时,完全原生的路径并非总是可行。在您仍需要支持基于密码的认证(利用 OAuth2)的场景中,完全的原生集成可能不可行,这使得 WebView 实现成为唯一可行的替代方案。WebView 充当一座桥梁,将 Web 内容直接嵌入到您的应用中,在浏览网页时提供类似浏览器的用户体验。如果您本身是 OAuth2 提供商,您底层的认证解决方案是基于 OAuth2 的,或者您的登录解决方案使用第三方社交登录(例如 Google 或 GitHub),这一点尤其重要。在这些情况下,由于需要与 Web 内容交互并管理各种用户认证流程,特别是在需要原生应用关联时,使用 WebView 变得不可避免。
总而言之,虽然原生实现提供了无与伦比的流畅用户体验,但它们可能并非总是可行的选择,尤其是在与基于密码或基于 OAuth2 的认证解决方案结合使用时。另一方面,WebView 实现提供了一条灵活(尽管无缝性稍差)的路径,用于在您的应用内集成 Web 内容和管理用户认证,确保您能够应对各种认证流程和第三方登录的复杂性。
本文接下来的部分将重点介绍通过 WebView 的实现。要了解更多关于原生 Passkey 集成的信息,请参阅此处。
Ben Gould
Head of Engineering
I’ve built hundreds of integrations in my time, including quite a few with identity providers and I’ve never been so impressed with a developer experience as I have been with Corbado.
10,000+ devs trust Corbado & make the Internet safer with passkeys. Got questions? We’ve written 150+ blog posts on passkeys.
Join Passkeys Community在原生应用认证的迷宫中穿行时,开发者和产品经理会面临一个关键决策:是原生实现 Passkey 认证,还是通过 WebView 实现。如果决定采用后者,iOS 和 Android 平台都提供了两种不同类型的 WebView,每种都有其独特的属性和潜在用例。
在以下部分,我们将深入探讨这些 WebView 类型,并最终指导您就应在原生应用中使用哪种 WebView 进行 Passkey 认证做出明智的决定(如果纯原生实现不是替代方案)。
iOS WebView 要么是 WKWebView,要么是 SFSafariViewController(如果使用 OAuth / OIDC,则是 SFAuthenticationSession / ASWebAuthenticationSession)。
为了测试 iOS 中不同 WebView 的行为,我们推荐使用应用 WebView - WKWebView and UIWebView rendering。
WKWebView 是一个功能强大且用途广泛的 WebView 选项,可供 iOS 开发者使用。它在 iOS 8 中引入,允许开发者将 Web 内容直接嵌入应用中,提供了广泛的自定义和配置选项。WKWebView 以其性能著称,使用与 Safari 相同的 Web 渲染引擎,并提供丰富的 API 用于与 Web 内容交互、管理导航、用户交互等。
SFSafariViewController 是一种 WebView,允许开发者直接在应用内利用 Safari 的功能。它通过使用用户的 Safari 设置(如已保存的密码、Passkey、Cookie 等)提供无缝的用户体验,确保一致的 Web 浏览体验,因为它实际上是作为 Safari 应用运行的。SFSafariViewController 的可定制性不如 WKWebView,但提供了增强的安全功能和易用性,使其成为在应用内显示直接 Web 内容的首选。
WKWebView | SFSafariViewController | |
---|---|---|
用户体验 | - 原生感: 用户可能会觉得 Web 内容是应用的原生部分,因为开发者可以自定义外观和感觉以匹配应用的设计。 - 自动填充: 可以使用来自 Safari 的数据进行自动填充。 | - 无缝: 使用用户的 Safari 设置,提供无缝的用户体验,确保原生应用和浏览器之间 Web 浏览的一致性。 |
开发者体验 | - 高度可定制: 提供广泛的自定义和配置。 - 灵活: 提供许多用于与 Web 内容交互的 API。 | - 中度可定制: 自定义选项有限,尤其与 WKWebView 相比。 - 简单: 与 WKWebView 相比,实现更简单。 |
性能 | - 相对较慢: 根据实现和 Web 内容,加载速度可以优化,但由于需要额外处理自定义功能和交互,可能仍比 SFSafariViewController 慢。 | - 相对较快: 通常性能更好,因为它利用了为速度和效率优化的 Safari 引擎,为网页提供快速的加载时间。 |
信任与识别 | - 无需显示 URL: WKWebView 通常不显示 URL,使用户更难验证网页。恶意应用有可能模仿此行为进行钓鱼凭证。 | - 类似浏览器的体验: 使用 Safari 渲染网页,提供“类似浏览器”的体验。用户可以看到 URL 并访问 Safari 的自动填充功能,熟悉的界面可能会带来更多信任。 |
隔离性 | - 分离: Cookie 和会话与 Safari 分离;用户不会自动登录到 WKWebView。 | - 分离: Cookie 和会话也与 Safari 分离;用户也不会自动登录到 SFSafariViewController。 |
漏洞 | - 安全: 由于苹果的应用沙盒机制,本身是安全的,但行为和安全性取决于应用的实现。如果实现不当,可能存在潜在漏洞。 | - 更安全: 受益于 Safari 内置的安全功能,包括反钓鱼和恶意网站警告。由于这些功能和用户对 Safari 的熟悉度,通常认为在显示 Web 内容方面比 WKWebView 更安全。 |
其他 | - 功能不可用: 由于安全考虑以及 WKWebView 在应用上下文中运行,某些浏览器功能(例如 WebAuthn)可能无法完全访问。 - JavaScript 注入: 一些应用,例如 TikTok,会在其应用内的 WKWebView 中注入跟踪 JavaScript,或限制用户控制(例如 Facebook)。 - 隐私问题: 关于隐私有更多的社区反馈。 | - 无 JavaScript 注入: 不允许从应用执行 JavaScript,增强了安全性和隐私性。它也不支持 JavaScript 警报或确认,可能会影响某些网页上的用户体验。 - 阅读模式: 提供阅读模式,以获得干净、易于阅读的文章版本。 |
SFAuthenticationSession 和 ASWebAuthenticationSession 是专为基于 OAuth / OpenID Connect 的认证流程量身定制的 WebView。它们为用户认证提供了一个安全和隔离的空间,保护用户凭证,并确保私人信息不会无意中与应用共享。这些会话与 Safari 共享 Cookie 和网站数据,提供一致和无缝的用户体验,尤其是在认证过程中。
优点:
缺点:
当主要任务是用户认证时,尤其是在实现 SSO 或与 OAuth 提供商交互时,您应该使用 SFAuthenticationSession / ASWebAuthenticationSession 而不是 SFSafariViewController。
Android WebView 要么是 WebView,要么是 Chrome 自定义标签页 (CCT)。为了测试 Android 中不同 WebView 的行为,我们推荐使用应用 WebView vs Chrome Custom Tabs。
Android 上的 WebView 是一个综合性组件,允许开发者将 Web 内容作为应用 UI 的一部分来显示。它用途广泛,提供广泛的自定义选项,并为开发者提供了配置 WebView 以适应各种需求的灵活性。WebView 提供了一套丰富的 API,用于与 Web 内容交互、管理用户交互,甚至处理 JavaScript 对话框、客户端证书和权限请求。
Chrome 自定义标签页 (CCT) 提供了一种无缝、安全且高效的方式,将 Web 内容直接集成到您的应用中。通过利用 Chrome 的功能和安全特性,CCT 提供了既一致又高性能的用户体验。
CCT 是 Chrome 浏览器的一个组件,旨在与 Android 框架集成,允许应用在一个轻量级的专用进程中打开 Web 内容。值得注意的是,它比传统浏览器打开得更快,并且当通过其预热调用进行预加载时,性能可能优于 WebView。虽然它执行 JavaScript,但它在自己的进程中运行,保护应用免受恶意代码的运行。此外,CCT 的 UI 提供了一个操作栏,显示 URL 和安全页面的 SSL 验证锁图标,从而让用户放心页面的真实性和安全性。
总的来说,可以说 iOS WKWebView 和 Android WebView,以及 SFSafariViewController 和 Chrome 自定义标签页 (CCT) 是相似的。
特性 | WebView | Chrome 自定义标签页 | |
---|---|---|---|
用户体验 | - 灵活性: 提供丰富的 API 用于与 Web 内容交互和管理用户交互,包括处理 JavaScript 对话框和权限请求。 - 一致性: 管理一致的用户体验,尤其是在处理各种 Web 内容时,可能具有挑战性。 | - 浏览器功能: 共享数据节省程序和跨设备同步的自动完成等功能。 - 返回按钮: 允许用户通过集成的返回按钮轻松返回应用。 - 依赖性: 依赖于 Chrome 应用,该应用可能并非在所有用户设备上都可用或已更新。 - 重定向到浏览器: 某些功能可能会将用户重定向到 Chrome 应用,可能会中断用户体验。 - 部分自定义标签页: 只有屏幕的一部分可用于 Chrome 自定义标签页,而其余部分显示原生应用。 - 侧边栏: 在横向模式和大屏幕设备上,Chrome 自定义标签页仅显示在屏幕的一侧,而屏幕的其余部分显示原生应用。 | |
开发者体验 | - 高度可定制: 提供广泛的自定义选项/需求。 - 交互性: 提供众多 API 用于与 Web 内容交互和管理用户交互。 | - 可定制: 允许自定义工具栏颜色、操作按钮、底部工具栏、自定义菜单项以及进入/退出动画。 - 回调: 在发生外部导航时向应用传递回调。 - 安全功能: 提供开箱即用的功能,无需管理请求、权限授予或 Cookie 存储。 | |
性能 | - 性能平平: 可能无法提供与 Chrome 自定义标签页 (CCT) 相同的性能水平。 | - 预热: 包括在后台预热浏览器和推测性加载 URL 以提高页面加载时间。 - 优先级: 通过将其重要性提升到“前台”级别,防止启动自定义标签页的应用在使用期间被系统回收。 | |
信任与识别 | - URL 和 SSL 不可见: URL 和 SSL 信息在 WebView 中本身是不可见的。除非应用开发者实现这些功能,否则用户无法知道他们是在正确的网站上还是在钓鱼网站上。 | - URL 和 SSL 可见: 使用实际的 Chrome 浏览器渲染页面。用户可以看到 URL 和 SSL 证书(指示连接是否安全)。这可以给用户信心,让他们相信自己不在钓鱼网站上。 | |
隔离性 | - 在应用的进程内运行: 如果应用存在允许恶意代码执行的漏洞,则存在 WebView 可能被攻破的风险。然而,WebView 也会收到更新,但其行为和安全性更依赖于使用它的应用。 - 无 Cookie / 会话共享: 不与设备的主浏览器共享 Cookie 或会话,提供了隔离性,但可能需要用户重新登录。 | - 在 Chrome 的进程内运行: 作为 Chrome 的一部分,自定义标签页在同一进程中运行,并具有与 Chrome 相同的安全更新和功能。 - 共享 Cookie 罐和权限模型: 确保用户不必重新登录网站或重新授予权限。 - Chrome 设置和偏好: 利用 Chrome 的设置和偏好。 | |
漏洞 | - 窃取凭证的回调: 潜在漏洞包括有时需要 JavaScript,这为其他应用运行恶意代码打开了大门,例如注册试图拦截用户名和密码的回调。 - 钓鱼: 此外,恶意应用可能会打开另一个模仿链接流程的网页,进行钓鱼尝试。 | - Google 安全浏览: 采用 Google 的安全浏览功能来保护用户和设备免受有害网站的侵害。 - 安全的浏览器装饰: 确保用户始终看到他们正在交互的确切 URL,并可以查看网站的证书信息,从而降低钓鱼风险。此外,自定义标签页不允许 JavaScript 注入。 | |
其他 | - Google 禁止使用 WebView 让用户登录 Google 帐户。 |
我们的客户不断询问我们应如何在原生应用中实现 Passkey。这些客户大致可以分为不同的组别:
A 组:
从零开始构建其原生应用的客户,可以直接使用我们的无密码认证(不存在旧密码)。
B 组:
拥有现有用户和现有认证解决方案的客户。通常他们也已经有一个现有的 Web 应用,也需要将 Passkey 添加到其认证流程中。这里许多公司决定采用两步流程:
确定您所属的组别
为了在原生应用中为您的用户提供最佳的 Passkey 实现,您需要根据您当前的技术设置以及您希望如何推广 Passkey(这个问题与 B 组的公司相关)来决定您属于哪个组别。
对 A 组的建议:原生实现
如果您正在构建一个全新的应用(A 组),我们建议采用原生 Passkey 实现,并立即完全无密码化(因此不使用任何类型的 WebView)。请使用 iOS 和 Android 的原生 SDK 和 API(例如,通过 passkeys Flutter 包)。也请阅读这篇关于依赖方 ID 的文章。
对 B 组的建议:先用 WebView,后用原生实现
如果您由于任何原因(B 组)今天无法原生实现 Passkey,您可以从 WebView 实现开始,然后在未来转向原生 Passkey 实现(这通过创建关联文件来实现,例如用于 iOS 应用的 apple-app-site-association 和用于 Android 应用的 assetlinks.json)。选择 WebView 实现的原因可能包括:
这是 Google 或 GitHub 目前在其原生应用中实现 Passkey 认证的方式。请参阅以下建议,以正确设置用于 Passkey 认证的 WebView。然而,我们建议考虑像 KAYAK 那样采用原生 Passkey 实现,并直接从第 2 步开始。
如果您属于 B 组且无法原生实现 Passkey,我们的建议倾向于在 iOS 上使用 SFAuthenticationSession / ASWebAuthenticationSession,在 Android 上使用 Chrome 自定义标签页(否则 Passkey 无论如何都无法工作)。
下面,我们陈述此建议的理由:
SFAuthenticationSession / ASWebAuthenticationSession 与 Safari 共享 Cookie 和网站数据,在认证过程中提供无缝的用户体验。这同样适用于 Android 上的 Chrome 自定义标签页。
用户可以从他们在浏览器中保存的密码、自动填充数据和其他存储信息中受益,使认证过程更顺畅、更快捷。
iOS 上的 SFAuthenticationSession / ASWebAuthenticationSession 和 Android 上的 Chrome 自定义标签页 为用户认证提供了一个安全和隔离的空间,确保敏感的用户凭证得到保护,不会无意中与应用或其他网站共享。
它们遵守苹果和谷歌严格的安全协议,确保用户数据得到安全处理并维护隐私。
此外,这种设计选择受益于 Safari 和 Chrome 持续的安全更新和增强功能,确保其遵守最新的安全标准和协议。
iOS 上的 SFAuthenticationSession / ASWebAuthenticationSession 和 Android 上的 Chrome 自定义标签页 提供了统一且熟悉的用户界面,因为用户习惯于浏览器的用户体验。此外,Safari 和 Chrome 的用户设置和偏好也会被应用。
它在应用内容和 Web 内容之间提供了平滑的过渡,确保用户不会因界面切换而感到突兀。
Chrome 自定义标签页 利用了 Chrome 的性能,确保了流畅和响应迅速的用户体验,这在认证过程中尤为关键,以防止用户感到沮丧或放弃。
CCT 的性能通常优于 Android WebView 选项(iOS 上的 SFAuthenticationSession / ASWebAuthenticationSession 也是如此),确保 Web 内容和认证流程能够迅速、平稳地处理。
另请参阅 Google 的这个比较,以感受 Chrome 自定义标签页、Android WebView 和标准 Chrome 浏览器之间的性能差异。
SFAuthenticationSession / ASWebAuthenticationSession 专为处理基于 OAuth / OpenID Connect 的认证流程而设计,为这些广泛使用的认证协议确保了简化和安全的过程。它也是 WebAuthn / Passkey 认证的推荐方式。
在 Android 上,没有专门用于认证流程的类,但可以使用 Chrome 自定义标签页 和 Android App Links 实现类似的行为。
此外,我们预计会有更多应用像 TikTok 一样引入 Passkey,仅仅在用户认证时收集它们。这可以原生实现(TikTok 的实现),也可以通过 WebView 实现。一个合适的方法是原生触发条件 UI。如果不行,则显示 WebView 实现。
在现代数字认证领域,通过 WebView 在原生应用中实现 Passkey 成为安全和用户友好实践的典范。虽然选择最佳 WebView 的过程可能错综复杂,但将技术选择与用户体验和安全性对齐至关重要。
Enjoyed this read?
🤝 Join our Passkeys Community
Share passkeys implementation tips and get support to free the world from passwords.
🚀 Subscribe to Substack
Get the latest news, strategies, and insights about passkeys sent straight to your inbox.
Related Articles
Cross‑Platform Passkey Sharing Guide: Flutter (iOS/Android), NextJS, Golang
Vincent - November 16, 2023
Passkey Tutorial: How to Implement Passkeys in Web Apps
Vincent - December 7, 2023
Table of Contents