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

编辑页面

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


For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.

认证是现代应用中 90% 到 95% 都离不开的关键部分。本指南将介绍常见的方法、模式和解决方案,帮助你在 Expo 应用中实现认证。

TL;DR:认证很难。如果你想跳过复杂性,直接跳到 Auth solutions 部分查看现成方案。否则,请继续阅读。

实现认证不仅仅是编写客户端代码。你还需要管理服务器请求、密码流程、Google 或 Apple 等第三方提供商、邮件处理以及 OAuth 标准。事情很快就会变得复杂起来。

认证方法有很多种。有些简单且有效,而另一些能提供更好的用户体验,但需要更多工作。让我们看看最常见的方法,以及你可以如何实现它们。

先从基础开始:任何认证系统都需要将 public screens(例如登录或注册)与 protected screens(例如首页或个人资料)区分开来。在导航层面,这归结为一个简单的判断:用户是否已认证?

一开始,你可以用一个硬编码的布尔值来模拟,比如 isAuthenticated = true,并围绕它构建你的导航逻辑。等一切都正常工作后,再接入真实的认证流程。

Using Expo Router

Expo Router v5 引入了 protected routes,它可以防止用户在未认证的情况下访问某些屏幕。这个功能非常适合客户端导航,并能简化你的设置。

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

Expo Router Protected Routes
Expo Router Protected Routes

了解如何使用 Expo Router 实现认证流程

Using React Navigation

如果你使用的是 React Navigation,它们提供了一份有用的 authentication flow guide,说明如何组织你的导航逻辑。其中包括基于用户认证状态的 staticdynamic 两种实现方式示例。

Expo Router 和 React Navigation 都为你提供了灵活的工具,可根据用户是否登录来实现受保护的导航。

Email and password

电子邮件和密码是为应用添加认证时很受欢迎的一种方式。

为了让这个流程更友好,你还需要实现忘记密码和重置密码功能,这样失去账户访问权限的用户就可以找回账户。

如果你想要更快的方案,许多服务都内置了电子邮件和密码认证,包括 ClerkSupabaseCognitoFirebaseBetter Auth。其中大多数都有相当宽松的免费额度,但如果你的应用增长很快,最好还是评估一下价格。

这些服务最大的优势在于集成简单。它们通常提供清晰的文档、入门模板和预构建组件,帮你节省时间。

Security checklist (OWASP) and store-review gotchas

如果你打算自己构建这个流程,请务必查看 OWASP 的 Authentication Cheat Sheet。它概述了密码长度、加密、恢复、安全存储等方面的最佳实践。

添加电子邮件和密码认证通常已经足够通过 App Store 和 Play Store 审核。你可以先用这种方式提交应用。如果你加入了“使用 Google 登录”,Apple 可能会拒绝你的应用,除非你同时支持“使用 Apple 登录”。在 Google Play 上则适用相反的规则。
Better Auth Example

一个演示使用 Better Auth 进行电子邮件和密码认证的示例。

Passwordless login

无密码登录让用户不必创建或记住密码。相反,他们在注册时提供电子邮件地址或电话号码。然后你的应用会向他们的收件箱或设备发送 magic linkone-time passcode (OTP)。这对大多数用户来说体验更流畅,也降低了入门门槛。

One-Time Passcodes (OTP)

除了 magic link,另一种方案是通过电子邮件或短信发送一次性验证码。用户不再点击链接,而是复制验证码并手动返回应用中输入。这个过程必须在验证码过期前的特定时间窗口内完成。

这里不涉及深度链接。用户自行掌控流程,并且必须自己回到应用中。

幸运的是,新版 Android 和 iOS 会自动识别来消息中的验证码。这会在键盘上方提供自动填充建议,让用户只需轻点一下就能输入验证码。当这个功能生效时,体验会非常顺畅。

Magic link 和验证码都是 Google Play Store 和 Apple App Store 审核认可的有效认证方式。你可以仅使用其中一种方式提交应用并获得批准,甚至在添加社交登录或 OAuth 登录选项之前也可以。

OAuth 2.0

如果你想让用户使用他们在 Google、Apple、GitHub 等服务中的现有账户登录,可以使用 OAuth 2.0。

OAuth 2.0 是一种广泛使用且安全的协议,它允许你的应用访问来自其他服务的用户信息,而无需处理密码。它让用户只需轻点一下即可登录,从而节省时间、建立信任,并省去了管理密码的需要。

OAuth 流程可能很复杂。如果你想要一个简单的集成,大多数提供商都提供 SDK 和服务来帮你处理一切。你可以在 Auth solutions 部分了解更多。

如果你希望拥有完全控制权,或者想了解 OAuth 底层是如何工作的,下面的章节将展示如何使用 Expo 自行实现完整的 OAuth 流程。

How OAuth works

OAuth 的工作方式是引入一个充当安全中介的授权服务器。用户不会把密码交给你的应用,而是通过这个服务器登录并批准对特定数据(比如姓名或邮箱)的访问。然后服务器会发出一个临时代码,你的应用可以用它换取安全的访问令牌。

在这张图中,'client' 仅指应用程序,并不暗示任何具体实现细节,例如它是否运行在服务器、桌面、移动设备或其他平台上。

一旦你理解了这种模式,就可以将其应用到任何提供商。Google、Apple 或 GitHub 的设置都将遵循相同的大致步骤。

Custom OAuth with Expo API Routes

前面的图展示了 OAuth 流程的高层概览。不过,客户端从用户那里获取授权授权的首选方式,是使用授权服务器作为中介,而这正是你可以通过 Expo API Routes 构建的内容。

下图会更详细地说明这个流程:

Expo 允许你直接在应用中使用以下方式实现完整的 OAuth 流程:

Expo Router
Expo Router API Routes
Expo AuthSession

有些提供商提供原生 API,可以直接在应用内处理登录流程。Google 在 Android 上提供原生的“使用 Google 登录”体验。如果你想要原生实现,请参见 Google authentication guide。Apple 提供 Sign in with Apple,它在 iOS 上使用原生底部弹窗和 Face ID。请参见 expo-apple-authentication 参考文档。

下面的设置可以让你在 Android、iOS 和 web 上完全控制登录体验。

What are Expo API Routes?

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

这使得在应用内部安全地处理认证流程中的敏感部分变得很容易,比如 authorization code exchange。由于这些路由运行在服务器上,你可以安全地管理密钥、签发 JWT,并验证令牌。

你本质上是在用自己的 Expo 项目构建一个轻量级、只服务于你应用的自定义认证服务器。
What is Expo AuthSession?

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

它是启动流程并在用户授权后与 API Route 通信的工具。更多信息请参见 Authentication with OAuth or OpenID providers

这个设置让你可以:

  • 使用 AuthSession 启动登录流程
  • 在你的 API Route 中接收 auth code
  • 安全地将代码兑换为 token
  • 使用你自己的逻辑生成自定义 JWT
  • 将该 token 返回给客户端
  • 使用 cookie(Web)或 JWT(Native)存储 session
  • 通过 EAS Hosting 立即部署(免费起步)

下面的教程介绍了如何在 Android、iOS 和 web 上实现 OAuth,包括如何创建和验证自定义 JWT、管理 session,以及保护 API 路由。如果你是第一次接触这个流程,建议从 Google 教程开始。

Google Sign-In with Expo OAuth
Google Sign-In with Expo OAuth

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


Sign in with Apple using Expo
Sign in with Apple using Expo

了解如何实现使用 Apple 登录


Managing sessions after OAuth

安全地处理 OAuth 流程只是开始。用户认证完成后,你还需要考虑如何存储、恢复和验证他们的 session。

这包括:

  • 在客户端安全地存储 session
  • 在应用重启时恢复 session
  • 保护你的 API 路由,以便只有已认证用户才能访问

传统上,web 会使用 cookies 来存储 session,而 JSON Web Tokens (JWTs) 则常见于原生应用。

上面的教程已经准确演示了如何处理这一切。在从 Google 或 Apple 之类的提供商收到 ID token 后,你会使用 Expo API Routes 在服务器上生成一个自定义 JWT。

这让你可以完全控制 session,包括:

  • 使用跨提供商一致的字段来构造载荷
  • 自定义过期时间
  • 使用密钥对 token 签名,以便服务器之后能够验证它

一旦 token 创建完成:

  • 对于 Android 和 iOS 应用,你可以使用 expo-secure-store 安全存储它
  • 对于 web 应用,你可以将其设置为安全 cookie 以维持 session

在每次请求中,token 都会被发送回你的服务器,服务器会验证签名并检查过期时间。如果一切通过,继续处理该请求。

这种 session 模型让你的后端保持无状态、可扩展且安全,并且能在不同平台间保持一致地工作。

以上所有内容都在上面链接的视频教程中有涵盖,包括:

  • 生成和验证自定义 JWT
  • 使用 Secure Store 和 cookies 处理 session 存储
  • 使用认证逻辑保护 API 路由

身份验证方案

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

Better Auth

BetterAuth 是一个现代的、开源的身份验证提供商,专为开发者打造。它与 Expo 集成顺畅,并且他们提供了一份指南,展示如何将其与 Expo API Routes 一起使用,以获得完全控制。它适用于任何提供商,并且可以通过 EAS Hosting 轻松部署。

Clerk

Clerk 是一项强大且功能全面的身份验证服务,对 Expo 的支持非常出色。它包含电子邮件/密码、验证码、魔法链接、OAuth 提供商,甚至通行密钥。他们还提供了一个原生 Expo 模块,可为你处理大部分集成工作。

Supabase

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

Cognito

AWS Cognito 是 Amazon 用于管理用户池和身份的解决方案。它可以与其他 AWS 服务无缝连接,并可使用 AWS Amplify 集成到 Expo 应用中。它确实需要更多配置,但它很稳健且可扩展。

Firebase Auth

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

现代方法

一旦你拥有了可用的身份验证系统,就可以通过添加可选但强大的增强功能来改善用户体验,例如生物识别和通行密钥。这些功能为你的登录流程增加了便利性、信任感和速度。

Biometrics

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

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

Passkeys

Passkeys 是一种新的、无需密码的登录应用和网站方式。在 Apple、Google 和 Microsoft 的支持下,它们使用平台级加密和生物识别技术,在无需密码的情况下验证用户身份。

Passkeys 提供了无缝且安全的体验,但它们要求用户在注册之前已经通过身份验证。如果你没有使用能为你处理它们的提供商,也需要额外配置。

建议

本指南涵盖了很多内容,从基础的电子邮件和密码流程,到完全自定义的 OAuth 实现、会话管理,以及生物识别和通行密钥等现代方法。并不需要一次性实现所有这些功能。

在许多情况下,从简单开始是最佳方案。用类似电子邮件身份验证的方式发布你的应用,例如使用魔法链接或一次性验证码,通常已经足以通过 App Store 审核流程,并开始收集真实用户的反馈。

话虽如此,如果你正在构建一个预计从第一天起就会有高流量,或者需要以尽可能低的摩擦支持跨平台登录的应用,那么尽早投资一个更完整的身份验证流程可以带来很大差异。它可以从一开始就帮助改善用户引导、信任和留存。

像 OAuth、生物识别和通行密钥这样的现代解决方案并非必需,但一旦你的核心系统就位,它们可以成为很好的补充。

关键在于构建一个符合你当前需求的身份验证系统,同时保持足够的灵活性,以便随着产品发展而扩展。