在 Expo 和 React Native 应用中的身份验证

编辑

了解如何在您的 Expo 项目中设置身份验证。


身份验证是现代应用中90%到95%的一个关键部分。本指南解释了常见的方法、模式和解决方案,以帮助您在 Expo 应用中实现身份验证。

TL;DR:身份验证很难。如果您想跳过复杂性,请跳到 身份验证解决方案 部分,获取即成解决方案。否则,请继续阅读。

实现身份验证不仅仅是编写客户端代码。您需要管理服务器请求、密码流程、第三方提供商(如 Google 或 Apple)、电子邮件处理和 OAuth 标准。这个过程会迅速变得复杂。

身份验证方法有几种类型。一些方法简单有效,而另一些方法提供更好的用户体验,但需要更多的工作。让我们看看最常见的方法以及如何实现它们。

导航身份验证流程

首先,让我们从基础知识开始:任何身份验证系统都需要将 公开屏幕(如登录或注册)与 受保护屏幕(如主页或个人资料)分开。在导航层面,这归结为一个简单的检查:用户是否已认证?

开始时,您可以使用硬编码的布尔值模拟此功能,例如 isAuthenticated = true,并围绕此构建导航逻辑。一旦一切正常工作,您可以插入真正的身份验证流程。

使用 Expo Router

Expo Router v5 引入了 受保护路由,它阻止用户在未认证的情况下访问某些屏幕。此功能非常适合客户端导航,并简化您的设置。

如果您使用的是旧版本的 Expo Router,您可以使用 重定向。重定向提供相同的结果,但需要更多的手动配置。为了向后兼容,它们在 Expo Router v5 中仍然受到支持。

Expo Router 受保护路由
Expo Router 受保护路由

了解如何使用 Expo Router 实现身份验证流程

使用 React Navigation

如果您使用的是 React Navigation,他们提供了一个有用的 身份验证流程指南,该指南解释了如何构建您的导航逻辑。它包含基于用户身份验证状态的 静态动态 方法的示例。

无论是 Expo Router 还是 React Navigation,都为您提供灵活的工具,以基于用户是否已登录实现受保护的导航。

电子邮件和密码

电子邮件和密码是为应用添加身份验证时的流行选择。

为了使此流程用户友好,您还需要实现忘记密码和重置密码的功能,以便失去访问权限的用户能够恢复账户。

如果您想要更快的解决方案,几项服务提供内置电子邮件和密码身份验证,包括 ClerkSupabaseCognitoFirebaseBetter Auth。其中大多数服务提供慷慨的免费层,但如果您的应用快速增长,评估定价是个好主意。

这些服务的最大优势是易于集成。它们通常提供清晰的文档、入门套件和预构建组件,节省您的时间。

安全检查清单(OWASP)和应用商店审核陷阱

如果您自己构建这个流程,请务必查看 OWASP 的 身份验证备忘单。它列出了密码长度、加密、恢复、可靠存储等方面的最佳实践。

添加电子邮件和密码身份验证通常足以通过 App Store 和 Play Store 审核。您可以先提交包含此方法的应用。如果您包括“使用 Google 登录”,Apple 可能会拒绝您的应用,除非您还支持“使用 Apple 登录”。在 Google Play 上,反向适用同样的规则。
Better Auth 示例

一个演示如何使用 Better Auth 进行电子邮件和密码身份验证的示例。

无密码登录

无密码登录消除了用户创建或记住密码的需要。相反,他们在注册时提供电子邮件地址或手机号码。您的应用随后会向他们的收件箱或设备发送一个 魔法链接一次性密码(OTP)。这为大多数用户提供了更流畅的体验,并减少了入门时的摩擦。

魔法链接

使用魔法链接,用户收到一封包含将他们重定向回您应用的链接的电子邮件。如果一切正常,会议将被验证和建立。

这里的一个关键细节是 深层链接。由于用户需要离开应用检查电子邮件,因此链接必须打开您的应用并将他们引导到正确的屏幕。如果深层链接失败,则无法验证会议,登录流程将中断。

如果您使用的是 Expo Router,则深层链接会自动处理(在大多数情况下)。您通常不需要配置任何额外的内容来使魔法链接正常工作,这使得此方法更易于采用。有关更多信息,请参阅 链接到您的应用

React Navigation 也支持深层链接,但您需要手动配置。有关更多详细信息,请查看其 深层链接指南

一次性密码(OTP)

魔法链接的另一种替代方案是通过电子邮件或短信发送一次性密码。用户无需点击链接,而是复制代码并手动返回应用输入。此操作必须在特定的时间窗口内完成,以便代码不会过期。

这里不涉及深层链接。用户控制着流程,必须自己返回应用。

幸运的是,较新的 Android 和 iOS 版本会自动检测到传入消息中的密码。这使得在键盘上方提供自动填充建议,允许用户通过一次点击输入代码。当这一过程顺利时,体验是无缝的。

魔法链接和一次性密码都是 Google Play Store 和 Apple App Store 审核的有效身份验证方法。您可以仅使用这些方法之一提交应用并获得批准,甚至在添加社交或 OAuth 登录选项之前。

OAuth 2.0

要让用户使用 Google、Apple、GitHub 等服务的现有账户登录,您可以使用 OAuth 2.0。

OAuth 2.0 是一种广泛使用的安全协议,允许您的应用访问来自其他服务的用户信息,而无需要处理密码。它让用户可以通过一次点击登录,节省时间,建立信任,并免去管理密码的需要。

OAuth 流程可能很复杂。如果您正在寻找简单的集成,大多数提供商都提供 SDK 和服务,帮您处理所有事情。您可以在 身份验证解决方案 部分中了解更多信息。

如果您希望完全控制或想了解 OAuth 的内部工作原理,以下部分将展示如何使用 Expo 自己实现完整的 OAuth 流程。

OAuth 的工作原理

OAuth 通过引入一个作为安全中介的授权服务器来工作。用户不将密码提供给您的应用,而是通过该服务器登录并批准访问特定数据(例如名称或电子邮件)。然后,服务器发放一个临时代码,您的应用可以用它来交换安全访问令牌。

在此图中,'客户端' 仅指应用程序,并不暗示任何特定的实现细节,例如它是否在服务器、桌面、移动设备或其他平台上运行。

一旦您了解了这一模式,您就可以将其应用于任何提供商。Google、Apple 或 GitHub 的设置将遵循相同的一般步骤。

使用 Expo API 路由的自定义 OAuth

前面的图表显示了 OAuth 流程的高级概述。然而,客户端获得用户的授权授予的首选方法是使用授权服务器作为中介,而这正是您可以使用 Expo API 路由构建的。

以下图表详细说明了这一流程:

Expo 让您可以在应用中直接实现整个 OAuth 流程,使用:

Expo Router
Expo Router API 路由
Expo AuthSession

一些提供商提供原生 API,以直接在应用内处理登录流程。Google 在 Android 上提供原生的使用 Google 登录体验。如果您正在寻找原生实现,请参阅 Google 身份验证指南。Apple 提供使用原生底部面板和 iOS 的面部识别的 Apple 登录。请查看 expo-apple-authentication 参考。

以下设置使您可以全面控制 Android、iOS 和 Web 的登录体验。

什么是 Expo API 路由?

Expo Router API 路由 允许您在 Expo 应用中直接编写服务器端逻辑。您可以定义处理请求的函数,就像 Express 或 Next.js 后端一样,无需外部服务器。

这使得可以轻松安全地处理身份验证流程中的敏感部分,例如 授权代码交换,直接在您的应用中进行。由于这些路由在服务器上运行,您可以安全地管理秘密、发行 JWT 和验证令牌。

您本质上是在为您自己的应用构建一个轻量级的自定义身份验证服务器,全部使用您的 Expo 项目。
什么是 Expo AuthSession?

Expo AuthSession 是一个客户端包,帮助您打开网页浏览器或原生模态以开始 OAuth 登录流程。它处理重定向、解析授权响应,并将用户带回您的应用。

这是启动流程的工具,并在用户授权访问后与您的 API 路由进行交互。有关更多信息,请参阅 使用 OAuth 或 OpenID 提供者的身份验证

此设置让您可以:

  • 使用 AuthSession 启动登录流程
  • 在您的 API 路由中接收身份验证代码
  • 安全地交换代码以获取令牌
  • 使用您自己的逻辑生成自定义 JWT
  • 将该令牌返回给客户端
  • 使用 Cookie(Web)或 JWT(原生)存储会话
  • 使用 EAS Hosting 立即部署(免费启动)

以下教程涵盖如何在 Android、iOS 和 Web 上实现 OAuth,包括如何创建和验证自定义 JWT、管理会话和保护 API 路由。如果您对这个流程不熟悉,建议从 Google 教程开始。

使用 Expo OAuth 实现 Google 登录
使用 Expo OAuth 实现 Google 登录

了解如何使用 Expo Router API 路由实现 Google 登录


使用 Expo 实现 Apple 登录
使用 Expo 实现 Apple 登录

了解如何实现 Apple 登录


在 OAuth 后管理会话

安全处理 OAuth 流程仅仅是开始。一旦用户通过身份验证,您还需要考虑如何存储、恢复和验证他们的会话。

这包括:

  • 在客户端安全地存储会话
  • 当应用重新启动时恢复会话
  • 保护您的 API 路由,以便只有经过身份验证的用户可以访问

传统上,Cookie 用于在 Web 上存储会话,而 JSON Web 令牌(JWT) 在原生应用中很常见。

以上教程准确地展示了如何处理这一点。在从 Google 或 Apple 等提供商接收到 ID 令牌后,您使用 Expo API 路由在服务器上生成自定义 JWT。

这让您全面控制会话,包括:

  • 使用各个提供商一致字段结构化有效负载
  • 自定义过期时间
  • 使用秘密密钥签署令牌,以便您的服务器可以稍后验证

一旦令牌创建:

  • 对于 Android 和 iOS 应用,您可以使用 expo-secure-store 安全地存储它
  • 对于 Web 应用,您可以将其设置为安全 Cookie,以维持会话

在每次请求中,令牌会发送回您的服务器,在那里您验证签名并检查过期。如果一切正常,您可以继续处理请求。

这种会话模型使您的后端保持无状态、可扩展且安全,在各个平台上始终如一地运行。

所有这些都在上述视频教程中涵盖,包括:

  • 生成和验证自定义 JWT
  • 使用 Secure Store 和 Cookie 处理会话存储
  • 使用身份验证逻辑保护 API 路由

身份验证解决方案

如果您不想从头开始构建完整的身份验证系统,有几项服务提供内置解决方案,并对 Expo 的支持一流。以下是一些最受欢迎的选项:

Better Auth

BetterAuth 是一个现代的开源身份验证提供商,专为开发人员构建。它与 Expo 的集成十分顺畅,他们提供一份指南,展示如何与 Expo API 路由 一起使用,以便进行全面控制。它可以很好地与任何提供商合作,并且容易与 EAS Hosting 部署。

Clerk

Clerk 是一个功能强大的全功能身份验证服务,具有出色的 Expo 支持。它包括电子邮件/密码、密码、魔法链接、OAuth 提供商,甚至是密码钥匙。它们还提供一个原生 Expo 模块,为您处理许多集成。

Supabase

Supabase 提供完整的后端平台,包括一个与任何 OAuth 提供商配合使用的内置身份验证服务。它与 Expo 应用集成良好,并且还支持电子邮件、魔法链接等。

Cognito

AWS Cognito 是亚马逊管理用户池和身份的解决方案。它与其他 AWS 服务无缝连接,并可以通过 AWS Amplify 集成到 Expo 应用中。虽然它需要更多的配置,但它功能强大且可扩展。

Firebase Auth

Firebase 身份验证 是谷歌的身份验证平台,支持电子邮件、魔法链接和 OAuth 提供商。它通过 react-native-firebase 与 React Native 兼容,该库与 Expo 开发构建兼容。

现代方法

一旦您的身份验证系统运行正常,您可以通过添加可选但强大的增强功能(如生物识别和密码钥匙)来改善用户体验。这些功能为您的登录流程增添了便利、信任和速度。

生物识别

生物识别技术,如 Face ID 和 Touch ID,可用于解锁应用或在有效会话建立后确认身份。这些不是独立的身份验证方法,而是作为一个本地网关,使重新身份验证更快、更安全。

React Native 通过像 expo-local-authenticationreact-native-biometrics 等库访问生物识别 API。

密码钥匙

密码钥匙 是一种新的无密码登录应用和网站的方式。受苹果、谷歌和微软支持,它们利用平台级加密技术和生物识别来无密码认证用户。

密码钥匙提供了无缝和安全的体验,但它要求用户在注册之前已经通过身份验证。如果您不使用负责处理它们的提供商,则还需要额外配置。

建议

本指南涵盖了许多内容,从基本的电子邮件和密码流程到完全自定义的 OAuth 实现、会话管理以及现代方法(如生物识别和密码钥匙)。并非所有内容都需要一次性实施。

在许多情况下,从简单的开始是最佳方法。使用像魔法链接或一次性密码这样的电子邮件认证方法发布应用通常就足够了,可以完成 App Store 审核流程,并开始收集真实用户的反馈。

也就是说,如果您正在构建一个预期从第一天就会有高流量的应用,或需要支持跨平台的登录并且摩擦最小,早期投资于更完整的身份验证流程会有很大差别。这可以帮助您从一开始就改善用户入门、信任和保留。

现代解决方案如 OAuth、生物识别和密码钥匙并不是必需的,但一旦核心系统建立,它们可以是很好的补充。

关键是构建适合您当前需求的身份验证,同时保持足够灵活,以便随着您的产品成长。