将您的应用程序连接到身份验证模拟器

在将身份验证模拟器与您的应用程序一起使用之前,请确保您了解 Firebase 本地模拟器套件的整体工作流程,并安装和配置本地模拟器套件并查看其CLI 命令

本主题假设您已经熟悉开发用于生产的 Firebase 身份验证解决方案。如果需要,请查看有关您的平台和身份验证技术组合的文档。

我可以使用身份验证模拟器做什么?

身份验证模拟器提供 Firebase 身份验证服务的高保真本地模拟,提供生产 Firebase 身份验证中的大部分功能。该模拟器与 Apple 平台、Android 和 Web Firebase SDK 配合使用,可让您:

  • 创建、更新和管理模拟用户帐户,用于测试电子邮件/密码、电话号码/SMS、SMS 多因素和第三方(例如 Google)身份提供商身份验证
  • 查看和编辑模拟用户
  • 原型定制令牌认证系统
  • 在 Emulator UI Logs 选项卡中检查与身份验证相关的消息。

选择一个 Firebase 项目

Firebase 本地模拟器套件模拟单个 Firebase 项目的产品。

要选择要使用的项目,在启动模拟器之前,请在 CLI 中在您的工作目录中运行firebase use 。或者,您可以将--project标志传递给每个模拟器命令。

Local Emulator Suite 支持模拟真实的Firebase 项目和演示项目。

项目类型特征与模拟器一起使用
真实的

真正的 Firebase 项目是您创建和配置的项目(很可能通过 Firebase 控制台)。

真实项目具有实时资源,例如数据库实例、存储桶、函数或您为该 Firebase 项目设置的任何其他资源。

在处理真正的 Firebase 项目时,您可以为任何或所有受支持的产品运行模拟器。

对于您未模拟的任何产品,您的应用程序和代码将与实时资源(数据库实例、存储桶、函数等)进行交互。

演示

演示 Firebase 项目没有真正的Firebase 配置,也没有实时资源。这些项目通常通过代码实验室或其他教程访问。

演示项目的项目 ID 具有demo-前缀。

使用演示 Firebase 项目时,您的应用和代码与模拟器交互。如果您的应用程序尝试与未运行模拟器的资源进行交互,则该代码将失败。

我们建议您尽可能使用演示项目。好处包括:

  • 设置更简单,因为您无需创建 Firebase 项目即可运行模拟器
  • 更强的安全性,因为如果您的代码意外调用非模拟(生产)资源,则不会发生数据更改、使用和计费
  • 更好的离线支持,因为无需访问互联网即可下载您的 SDK 配置。

检测您的应用程序以与模拟器对话

Android、iOS 和 Web SDK

设置您的应用内配置或测试类以与身份验证模拟器交互,如下所示。

安卓
FirebaseAuth.getInstance().useEmulator("10.0.2.", 9099);
迅速
Auth.auth().useEmulator(withHost:"localhost", port:9099)

Web version 9

import { getAuth, connectAuthEmulator } from "firebase/auth";

const auth = getAuth();
connectAuthEmulator(auth, "http://localhost:9099");

Web version 8

const auth = firebase.auth();
auth.useEmulator("http://localhost:9099");

无需额外设置即可原型化和测试身份验证与 Cloud Functions 或 Cloud Firestore 或实时数据库的 Firebase 安全规则之间的交互。当配置了身份验证模拟器并且其他模拟器正在运行时,它们会自动协同工作。

管理 SDK

设置FIREBASE_AUTH_EMULATOR_HOST环境变量后,Firebase Admin SDK 会自动连接到身份验证模拟器。

export FIREBASE_AUTH_EMULATOR_HOST="localhost:9099"

请注意,Cloud Functions 模拟器会自动识别 Authentication 模拟器,因此您可以在测试 Cloud Functions 和 Authentication 模拟器之间的集成时跳过此步骤。 Cloud Functions 中的 Admin SDK 会自动设置环境变量。

设置环境变量后,Firebase Admin SDK 将接受身份验证模拟器发出的未签名 ID 令牌和会话 cookie(分别通过verifyIdTokencreateSessionCookie方法),以方便本地开发和测试。请确保不要在生产中设置环境变量。

如果您希望您的 Admin SDK 代码连接到在另一个环境中运行的共享模拟器,则需要指定您使用 Firebase CLI 设置的相同项目 ID 。您可以将项目 ID 直接传递给initializeApp或设置GCLOUD_PROJECT环境变量。

Node.js 管理 SDK
admin.initializeApp({ projectId: "your-project-id" });
环境变量
export GCLOUD_PROJECT="your-project-id"

身份令牌

出于安全原因,身份验证模拟器会发出未签名的 ID 令牌,这些令牌仅在配置后被其他 Firebase 模拟器或 Firebase Admin SDK 接受。这些令牌将被生产 Firebase 服务或在生产模式下运行的 Firebase Admin SDK 拒绝(例如,没有上述设置步骤的默认行为)。

启动模拟器

您可以通过 Emulator Suite UI 以交互方式使用身份验证模拟器,也可以通过其本地 REST 接口以非交互方式使用身份验证模拟器。以下部分涵盖交互式和非交互式用例。

要启动 Authentication 模拟器、它的 REST 接口和 Emulator Suite UI,请执行:

firebase emulators:start

对于匿名身份验证,您的应用可以为您的平台( iOSAndroidWeb )执行登录逻辑。

对于电子邮件/密码身份验证,您可以通过使用身份验证 SDK 方法或使用 Emulator Suite UI 从您的应用程序将用户帐户添加到身份验证模拟器来开始原型设计。

  1. 在 Emulator Suite UI 中,单击身份验证选项卡。
  2. 单击添加用户按钮。
  3. 按照用户帐户创建向导,填写电子邮件身份验证字段。

创建测试用户后,您的应用可以使用适用于您的平台( iOSAndroidWeb )的 SDK 逻辑登录和注销用户。

为了使用电子邮件链接流测试电子邮件验证/登录,模拟器将 URL 打印到执行firebase emulators:start的终端。

i  To verify the email address customer@ex.com, follow this link:
http://localhost:9099/emulator/action?mode=verifyEmail&lang=en&oobCode=XYZ123&apiKey=fake-api-key

将链接粘贴到浏览器中模拟验证事件,并检查验证是否成功。

{
  "authEmulator": {
    "success": "The email has been successfully verified.",
    "email": "customer@example.com"
  }
}

为了测试密码重置,模拟器会向终端打印一个类似的 URL,包括一个newPassword参数(您可以根据需要更改)。

http://localhost:9099/emulator/action?mode=resetPassword&oobCode=XYZ!23&apiKey=fake-api-key&newPassword=YOUR_NEW_PASSWORD

非交互式测试

无需使用 Emulator Suite UI 或客户端代码来管理电子邮件/密码用户帐户,您可以编写测试设置脚本,调用 REST API 来创建和删除用户帐户并获取带外电子邮件验证码以填充模拟器电子邮件验证网址。这使平台和测试代码保持分离,并允许您进行非交互测试。

对于非交互式电子邮件和密码测试流程,典型顺序如下。

  1. 使用身份验证注册 REST 端点创建用户。
  2. 使用电子邮件和密码登录用户以执行测试。
  3. 如果适用于您的测试,请从特定于模拟器的 REST 端点获取可用的带外电子邮件验证码。
  4. 使用特定于模拟器的 REST 端点刷新用户记录以清除数据。

模拟电话/短信验证

对于电话认证,Auth 模拟器不支持:

  • reCAPTCHA 和 APN 流。一旦配置为与模拟器交互,客户端 SDK 就会以类似于集成测试( iOSAndroidweb )描述的方式禁用这些验证方法。
  • 使用 Firebase 控制台中预配置的代码测试电话号码。

否则,就客户端代码而言,电话/SMS 身份验证流程与为生产( iOSAndroidweb )描述的流程相同。

使用模拟器套件 UI:

  1. 在 Emulator Suite UI 中,单击身份验证选项卡。
  2. 单击添加用户按钮。
  3. 按照用户帐户创建向导,填写电话身份验证字段。

但是,对于电话身份验证流程,模拟器不会触发任何文本消息的传递,因为联系运营商超出了范围,并且对本地测试不友好!相反,模拟器会打印出通过 SMS 发送到您运行firebase emulators:start的同一终端的代码;将此代码输入到应用程序以模拟用户检查他们的短信。

非交互式测试

对于非交互式电话身份验证测试,请使用身份验证模拟器 REST API 来检索可用的 SMS 代码。请注意,每次启动流程时代码都不同。

典型的顺序如下。

  1. 调用平台signInWithPhoneNumber开始验证过程。
  2. 使用特定于模拟器的 REST 端点检索验证码。
  3. 像往常一样使用验证码调用confirmationResult.confirm(code)

多因素短信

身份验证模拟器支持对iOSAndroidweb生产中可用的 SMS 多因素身份验证 (MFA) 流进行原型设计和测试。

当您将模拟用户添加到模拟器时,您可以启用 MFA 并配置一个或多个电话号码,第二因素 SMS 消息将发送到该号码。消息将输出到您运行firebase emulators:start的同一终端,并且可以从 REST 界面获得。

模拟第三方身份提供者 (IDP) 身份验证

身份验证模拟器让您可以在您的 iOS、Android 或 Web 应用程序中测试许多第三方身份验证流程,而无需更改生产代码。有关身份验证流程的示例,请参阅文档以了解您可以在应用程序中使用的各种提供程序和平台组合

一般来说,您可以使用 Firebase SDK 通过以下两种方式之一进行身份验证:

  • 您的应用程序允许 SDK 端到端地处理整个流程,包括与第三方 IDP 提供商的所有交互以检索凭据。
  • 您的应用程序使用第三方提供商的 SDK 手动检索凭据,并将这些凭据传递给身份验证 SDK。

再次检查上面的文档链接,并确保您熟悉要使用的流程 - Firebase SDK 管理与手动凭证检索。身份验证模拟器支持对任一方法的测试。

测试 Firebase SDK 驱动的 IDP 流

如果您的应用使用任何 Firebase SDK 端到端流程(例如用于使用 Microsoft、GitHub 或 Yahoo 登录的OAuthProvider )进行交互式测试,则身份验证模拟器会提供相应登录页面的本地版本来帮助您进行测试来自调用signinWithPopupsignInWithRedirect方法的 Web 应用程序的身份验证。这个本地服务的登录页面也出现在移动应用程序中,由您平台的 webview 库呈现。

随着流程的进行,模拟器会根据需要创建模拟的第三方用户帐户和凭据。

使用手动凭据检索测试 IDP 流

如果您使用“手动”登录技术并调用您平台的signInWithCredentials方法,那么您的应用将像往常一样请求真正的第三方登录并检索真正的第三方凭据。

请注意,模拟器仅支持对从 Google Sign-In、Apple 和其他使用实现为 JSON Web 令牌 (JWT) 的 ID 令牌的提供商检索的凭据进行signInWithCredential身份验证。不支持访问令牌(例如由 Facebook 或 Twitter 提供的令牌,它们不是 JWT)。下一节将讨论这些情况下的替代方案。

非交互式测试

非交互式测试的一种方法是自动化用户点击模拟器提供的登录页面。对于 Web 应用程序,请使用 WebDriver 之类的控制界面。对于移动设备,请使用您平台上的 UI 测试工具,例如 Espresso 或 Xcode。

或者,您可以更新您的代码以使用signInWithCredential (例如在代码分支中),并使用带有模拟 ID 令牌的令牌身份验证流程来代替真实凭据。

  1. 重新连接或注释掉从 IDP 中检索 idToken 的代码部分;这消除了在测试期间输入真实用户名和密码的需要,并使您的测试免受 IDP 的 API 配额和速率限制。
  2. 其次,使用文字 JSON 字符串代替signInWithCredential的标记。以 web SDK 为例,您可以将代码更改为:
firebase.auth().signInWithCredential(firebase.auth.GoogleAuthProvider.credential(
  '{"sub": "abc123", "email": "foo@example.com", "email_verified": true}'
));

当与模拟器一起使用时,此代码将成功地通过电子邮件foo@example.com在 Google 对用户进行身份验证。将子字段视为主键,可以更改为任何字符串,模拟不同用户的登录。例如,您可以将firebase.auth.GoogleAuthProvider替换为new firebase.auth.OAuthProvider('yahoo.com')或您要模拟的任何其他提供商 ID。

模拟自定义令牌身份验证

身份验证模拟器使用自定义 JSON Web 令牌在受支持的平台上调用signInWithCustomToken方法来处理身份验证,如生产身份验证文档中所述。

身份验证模拟器与生产的不同之处

Firebase 身份验证模拟器模拟了生产产品的许多功能。但是,由于任何类型的身份验证系统都严重依赖于多个级别(设备、第 3 方提供商、Firebase 等)的安全性,因此模拟器很难正确地重新创建所有流。

云 IAM

Firebase Emulator Suite 不会尝试复制或尊重任何与 IAM 相关的运行行为。模拟器遵守提供的 Firebase 安全规则,但在通常使用 IAM 的情况下,例如设置调用服务帐户的 Cloud Functions 并因此设置权限,模拟器是不可配置的,并将使用您的开发人员机器上的全局可用帐户,类似于直接运行本地脚本。

由于在移动平台上,电子邮件链接登录依赖于 Firebase 动态链接,因此所有此类链接都将在(移动)网络平台上打开。

第三方登录

对于第三方登录流程,Firebase 身份验证依赖于来自 Twitter 和 Github 等第三方提供商的安全凭证。

身份验证模拟器接受来自 OpenID Connect 提供商(例如 Google 和 Apple)的真实凭据。不支持来自非 OpenID Connect 提供者的凭证。

电子邮件/短信登录

在生产应用程序中,电子邮件和 SMS 登录流程涉及异步操作,其中用户检查收到的消息并将登录代码输入登录界面。 Authentication 模拟器不发送任何电子邮件或 SMS 消息,但如上所述,它会生成登录代码并将其输出到终端以用于测试。

模拟器不支持使用 Firebase 控制台定义具有固定登录代码的测试电话号码的功能。

自定义令牌认证

身份验证模拟器不验证自定义令牌的签名或过期。这使您可以在原型设计和测试场景中无限期地使用手工制作的令牌和重复使用令牌。

速率限制/反滥用

身份验证模拟器不复制生产速率限制或反滥用功能。

接下来是什么?