App Check Web Codelab

1. 简介

上次更新日期:2023 年 2 月 23 日

如何防止他人未经授权访问您的 Firebase 资源?

您可以使用 Firebase App Check 来防止未经授权的客户端访问您的后端资源,方法是要求传入的请求附带证明,证明该请求来自您的真实应用,并阻止没有适当证明的流量。Firebase App Check 依赖于平台专属的证明提供方来验证客户端的真实性:对于 Web 应用,App Check 支持 reCAPTCHA v3 和 reCAPTCHA Enterprise 作为证明提供方。

App Check 可用于保护向 Cloud Firestore、Realtime Database、Cloud Functions、Firebase Authentication with Identity Platform 以及您自己托管的后端发出的请求。

构建内容

在此 Codelab 中,您将通过先添加 App Check 然后强制执行 App Check 来保护聊天应用。

您构建的初始 Friendly Chat 应用。

学习内容

  • 如何监控后端是否存在未经授权的访问
  • 如何为 Firestore 和 Cloud Storage 添加强制执行
  • 如何使用调试令牌运行应用以进行本地开发

所需条件

  • 您常用的 IDE/文本编辑器
  • 软件包管理器 npm,通常随 Node.js 一起提供
  • 已安装 Firebase CLI 并将其配置为与您的账号搭配使用
  • 终端/控制台
  • 您所选的浏览器(例如 Chrome)
  • Codelab 的示例代码(请参阅 Codelab 的下一步,了解如何获取代码。)

2. 获取示例代码

从命令行克隆此 Codelab 的 GitHub 代码库:

git clone https://github.com/firebase/codelab-friendlychat-web

或者,如果您未安装 Git,可以下载 ZIP 文件形式的代码库。

导入 starter 应用

使用 IDE 打开或导入克隆的代码库中的 📁 appcheck-start 目录。📁 appcheck-start 目录包含此 Codelab 的起始代码,该代码将是一个功能齐全的聊天 Web 应用。📁 appcheck 目录将包含此 Codelab 的完整代码。

3. 创建和设置 Firebase 项目

创建 Firebase 项目

  1. 使用您的 Google 账号登录 Firebase 控制台。
  2. 点击相应按钮以创建新项目,然后输入项目名称(例如 FriendlyChat)。
  3. 点击继续。
  4. 如果看到相关提示,请查看并接受 Firebase 条款,然后点击继续。
  5. (可选)在 Firebase 控制台中启用 AI 辅助功能(称为“Gemini in Firebase”)。
  6. 对于此 Codelab,您不需要使用 Google Analytics,因此请关闭 Google Analytics 选项。
  7. 点击创建项目,等待您的项目完成预配,然后点击继续。

升级您的 Firebase 定价方案

如需使用 Cloud Storage for Firebase,您的 Firebase 项目必须采用随用随付 (Blaze) 定价方案,这意味着该项目需要与一个 Cloud Billing 账号相关联。

  • Cloud Billing 账号要求提供付款方式,例如信用卡。
  • 如果您刚开始接触 Firebase 和 Google Cloud,请确认您是否有资格获得 $300 赠金和免费试用 Cloud Billing 账号。
  • 如果您是在活动中学习本 Codelab,请询问活动组织者是否有可用的 Cloud 赠金。

如需将项目升级到 Blaze 方案,请按以下步骤操作:

  1. 在 Firebase 控制台中,选择升级您的方案。
  2. 选择 Blaze 方案。按照屏幕上的说明将 Cloud Billing 账号与您的项目相关联。
    如果您需要在此升级过程中创建 Cloud Billing 账号,则可能需要返回 Firebase 控制台中的升级流程以完成升级。

向项目添加 Firebase Web 应用

  1. 点击 Web 图标 58d6543a156e56f9.png,创建新的 Firebase Web 应用。
  2. 使用昵称“Friendly Chat”注册应用,然后选中还为此应用设置 Firebase Hosting。点击注册应用。
  3. 在下一步中,您将看到一个使用 npm 安装 Firebase 的命令和一个配置对象。您将在本 Codelab 的后续步骤中复制此对象,因此现在请按下一步。

“将 Firebase 添加到您的 Web 应用”窗口

  1. 然后,您会看到安装 Firebase CLI 的选项。如果您尚未安装,请立即使用 npm install -g firebase-tools 命令进行安装。然后点击下一步。
  2. 然后,您会看到一个选项,用于登录 Firebase 并部署到 Firebase Hosting。使用命令 firebase login 登录 Firebase,然后点击继续并前往控制台。您将在后续步骤中部署到 Firebase Hosting。

设置 Firebase 产品

我们将要构建的应用会使用适用于 Web 应用的 Firebase 产品:

  • Firebase Authentication,可让用户轻松登录您的应用。
  • Cloud Firestore,用于在云端保存结构化数据,并在数据发生变化时即时收到通知。
  • Cloud Storage for Firebase,用于在云端保存文件。
  • Firebase Hosting,用于托管和提供您的资源。
  • Firebase Cloud Messaging,用于发送推送通知和显示浏览器弹出式通知。
  • Firebase Performance Monitoring,用于收集应用的用户性能数据。

其中一些产品需要进行特殊配置,或需要使用 Firebase 控制台启用。

为 Firebase Authentication 启用 Google 登录

为了让用户能够使用其 Google 账号登录 Web 应用,我们将使用 Google 登录方法。

您需要启用 Google 登录:

  1. 在 Firebase 控制台中,找到左侧面板中的构建部分。
  2. 点击 Authentication,然后点击 Get Started(如果适用),再点击 Sign-in method 标签页(或点击此处直接进入该标签页)。
  3. 启用 Google 登录提供方
  4. 将应用的公开名称设置为 Friendly Chat,然后从下拉菜单中选择项目支持电子邮件。
  5. 点击保存

f96888973c3d00cc.png

设置 Cloud Firestore

该 Web 应用使用 Cloud Firestore 保存聊天消息并接收新的聊天消息。

以下是在 Firebase 项目中设置 Cloud Firestore 的方法:

  1. 在 Firebase 控制台的左侧面板中,展开构建,然后选择 Firestore 数据库。
  2. 点击创建数据库。
  3. 将数据库 ID 保持设置为 (default)。
  4. 为数据库选择一个位置,然后点击下一步。
    对于真实应用,您需要选择靠近用户的位置。
  5. 点击以测试模式开始。阅读有关安全规则的免责声明。
    在本 Codelab 的后面部分,您将添加安全规则来保护您的数据。在没有为数据库添加安全规则的情况下,请不要公开分发或公开应用。
  6. 点击创建。

设置 Cloud Storage for Firebase

该 Web 应用使用 Cloud Storage for Firebase 来存储、上传和分享图片。

以下是在 Firebase 项目中设置 Cloud Storage for Firebase 的方法:

  1. 在 Firebase 控制台的左侧面板中,展开构建,然后选择 Storage。
  2. 点击开始使用。
  3. 为默认 Storage 存储桶选择一个位置。
    US-WEST1、US-CENTRAL1 和 US-EAST1 中的存储桶可为 Google Cloud Storage 使用“始终免费”层级。所有其他位置的存储桶都遵循 Google Cloud Storage 价格和用量。
  4. 点击以测试模式开始。阅读有关安全规则的免责声明。
    在本 Codelab 的后面部分,您将添加安全规则来保护您的数据。在未为您的存储桶添加安全规则的情况下,请不要公开分发或公开应用。
  5. 点击创建。

4. 配置 Firebase

从 appcheck-start 目录中,调用:

firebase use --add

出现提示时,选择您的项目 ID,然后为您的 Firebase 项目指定一个别名。对于此项目,您只需提供别名 default。接下来,您需要配置本地项目,使其能够与 Firebase 搭配使用。

  1. 前往 Firebase 控制台中的“项目设置”
  2. 在“您的应用”卡片中,选择需要配置对象的应用的别名。
  3. 从 Firebase SDK 代码段窗格中选择配置。
  4. 复制配置对象代码段,然后将其添加到 appcheck-start/hosting/src/firebase-config.js。此 Codelab 的其余部分假定该变量名为 config。

firebase-config.js

const config = {
  apiKey: "API_KEY",
  authDomain: "PROJECT_ID.firebaseapp.com",
  databaseURL: "https://PROJECT_ID.firebaseio.com",
  projectId: "PROJECT_ID",
  storageBucket: "PROJECT_ID.firebasestorage.app",
  messagingSenderId: "SENDER_ID",
  appId: "APP_ID",
  measurementId: "G-MEASUREMENT_ID",
};

在同一 appcheck-start 目录中,调用:

firebase experiments:enable webframeworks

这样可以启用 Web 框架支持,此项目就是使用该支持构建的。

现在,我们应该已经准备好运行项目并测试默认项目是否正常运行!

5. 在不使用 App Check 的情况下试用应用

现在,您已配置好应用并设置好 SDK,请尝试按照最初的设计使用该应用。首先,安装所有依赖项。在终端中,前往 appcheck-start/hosting 目录。在该目录中,运行 npm install。此命令会提取项目运行所需的所有依赖项。如需以当前状态启动应用,您可以运行 firebase serve。应用会要求您使用 Google 账号登录;登录后,尝试在聊天中发布一些聊天消息和照片。

现在,您已在本地进行了测试,接下来可以看看它在生产环境中的表现了!运行 firebase deploy,将 Web 应用部署到网络。此部分是演示 App Check 在实际场景中如何运作的关键步骤,因为需要为 reCAPTCHA Enterprise 证明提供方配置一个网域。

希望您能体验到该应用提供的默认功能。发布聊天消息以及其他所有只能通过此类应用完成的操作。当前状态的缺点是,任何拥有您在上一步中获取的应用配置的人都可以访问您的后端资源。他们仍然需要遵守 Firestore 和 Cloud Storage 系统中现有的安全规则,但除此之外,他们仍然可以查询、存储和访问存储在其中的数据。

在接下来的几个步骤中,您将:

  • 注册 App Check
  • 验证强制执行
  • 开始强制执行规则

6. 启用 App Check 并强制执行

首先,为您的项目获取 reCAPTCHA Enterprise 密钥,并将其添加到 App Check。首先,访问 Google Cloud 控制台的 reCAPTCHA Enterprise 部分。选择您的项目,然后系统会提示您启用 reCAPTCHA Enterprise API。启用该 API,并等待几分钟,让其完成。然后点击企业密钥旁边的创建密钥。然后,在此部分中指定显示名称,并选择网站类型的密钥。您需要指定用于托管应用的网域。由于您计划在 Firebase Hosting 上托管此应用,因此您可以使用默认主机名,通常为 ${YOUR_PROJECT_ID}.web.app。您可以在 Firebase 控制台的 Hosting 部分找到托管网域。填写完这些信息后,点击完成和创建密钥。

reCAPTCHA 创建密钥界面

完成后,您会在密钥详情页面顶部看到一个 ID。

reCAPTCHA Enterprise 注册窗口

请将此 ID 复制到剪贴板。这是您用于 App Check 的密钥。接下来,访问 Firebase 控制台的 App Check 部分,然后点击开始。然后,点击 Register(注册),再点击 reCAPTCHA Enterprise,并将复制的 ID 粘贴到 reCAPTCHA Enterprise Site Key(reCAPTCHA Enterprise 网站密钥)文本框中。将其余设置保留为默认值。您的 App Check 页面应如下所示:

App Check 应用窗口,您可以在其中注册 reCAPTCHA Enterprise 令牌

未验证和未强制执行的请求

现在,您已在 Firebase 控制台中注册了密钥,请运行 firebase serve,返回到在浏览器中运行网站。现在,Web 应用已在本地运行,您可以再次开始向 Firebase 后端发出请求。当请求发送到 Firebase 后端时,App Check 会监控这些请求,但不会强制执行。如果您想查看传入请求的状态,可以访问 Firebase 控制台中 App Check 页面“API”标签页内的 Cloud Firestore 部分。由于您尚未将客户端配置为使用 App Check,因此您应该会看到如下内容:

App Check 信息中心显示,您的应用有 100% 的客户端请求未经验证。

后端收到的请求 100% 未经验证。此界面非常有用,因为它显示几乎所有客户端请求都来自未集成 App Check 的客户端。

此信息中心可以反映以下几种情况。首先,它可以指示您的所有客户端应用是否都在运行最新版本的客户端。如果是,您就可以放心地强制执行 App Check,而不必担心会关闭应用的真实客户端的访问权限。此外,这还可能告诉您,有多少次访问后端的尝试并非来自您的应用。这可能是用户在您不知情的情况下直接查询您的后端。既然您已经看到请求未经验证,那么在继续验证这些请求之前,您需要了解那些可能向您的后端发送未经验证请求的用户会受到什么影响。

未经验证和已强制执行的请求

继续操作,在上一个屏幕中按强制执行按钮,然后按提示再次按强制执行。

未经验证的指标信息中心,其中突出显示了“强制执行”按钮

这将开始强制执行 App Check;现在,它会阻止对未通过您选择的证明提供方(在本例中为 reCAPTCHA Enterprise)验证的后端服务的请求。返回到正在运行的 Web 应用,该应用应该在 http://localhost:5000 运行。当您刷新页面并尝试从数据库获取数据时,没有任何反应。如果您打开 Chrome 控制台查看错误,应该会看到类似以下内容:

Uncaught Error in snapshot listener: FirebaseError: [code=permission-denied]: Missing or insufficient permissions.

这是因为 App Check 屏蔽了未在向 Firebase 资源发出的请求中传递有效证明令牌的请求。目前,您可以关闭 App Check 强制执行功能,在下一部分中,您将了解如何将 reCAPTCHA Enterprise App Check 添加到 Friendly Chat 示例中。

7. 将 reCAPTCHA Enterprise 密钥添加到网站

我们将向您的应用添加企业密钥。首先,打开 hosting/src/firebase-config.js,并将 reCAPTCHA Enterprise 密钥添加到以下代码段中:

const reCAPTCHAEnterpriseKey = {
  // Replace with your recaptcha enterprise site key
  key: "Replace with your recaptcha enterprise site key"
};

完成后,打开 hosting/src/index.js,在第 51 行,您将添加从 firebase-config.js 导入的内容,以提取 reCAPTCHA 密钥,并导入 App Check 库,以便您可以使用 reCAPTCHA Enterprise 提供程序。

// add from here
 import {
   initializeAppCheck,
   ReCaptchaEnterpriseProvider,
 } from 'firebase/app-check';
// to here

// replace this line
import { getFirebaseConfig } from './firebase-config.js';
// with this line
import { getFirebaseConfig, getReCaptchaKey } from './firebase-config.js';

然后,在下一行中,您将创建一个函数来设置 App Check。该函数会首先检查您是否处于开发环境中,如果是,则会输出一个可用于本地开发的调试令牌。

import { getFirebaseConfig, getReCaptchaKey } from './firebase-config.js';
// add from here
 function setupAppCheck(app) {
   if(import.meta.env.MODE === 'development') {
     self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
   }
 }
// to here

现在,您需要初始化 App Check,以便与所选提供方(在本例中为 reCAPTCHA Enterprise)搭配使用。您可能还希望在后台自动刷新 App Check 令牌,这样可以防止在 App Check 令牌失效时,用户与您的服务互动出现任何类型的延迟。

function setupAppCheck(app) {
   if(import.meta.env.MODE === 'development') {
     self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
   }
// add from here
   // Create a ReCaptchaEnterpriseProvider instance using your reCAPTCHA Enterprise
   // site key and pass it to initializeAppCheck().
   initializeAppCheck(app, {
     provider: new ReCaptchaEnterpriseProvider(getReCaptchaKey()),
     isTokenAutoRefreshEnabled: true // Set to true to allow auto-refresh.
   });
// to here
 }

最后,在确保应用已初始化后,您需要调用刚刚创建的 setupAppCheck 函数。在 hosting/src/index.js 文件的底部,添加对您最近添加的方法的调用。

const firebaseApp = initializeApp(getFirebaseConfig());
// add from here
setupAppCheck(firebaseApp);
// to here
getPerformance();
initFirebaseAuth();
loadMessages();

先在本地测试

首先在本地测试应用。如果您尚未在本地运行应用,请运行 firebase serve。您应该会注意到,应用仍然无法在本地加载。这是因为您只向 reCAPTCHA 证明提供方注册了 Firebase 网域,而未注册 localhost 网域。切勿将 localhost 注册为已获批准的网域,因为这会允许用户从其机器上本地运行的应用访问受限后端。相反,由于您设置了 self.FIREBASE_APPCHECK_DEBUG_TOKEN = true,因此您需要在 JavaScript 控制台中检查是否有类似以下内容的行:

App Check debug token: 55183c20-de61-4438-85e6-8065789265be. You will need to add it to your app's App Check settings in the Firebase console for it to work.

您需要获取提供的调试令牌(在本示例中为:55183c20-de61-4438-85e6-8065789265be),并将其插入到应用的溢出菜单下的 App Check 配置中。

App Check 信息中心,其中显示了“管理调试令牌”的位置

为令牌指定一个您能记住的唯一名称,然后点击保存。此选项允许您在应用中使用客户端生成的令牌,这比生成调试令牌并将其嵌入应用中更安全。在应用中嵌入令牌可能会导致令牌意外分发给最终用户,而这些最终用户可能会利用该令牌绕过您的检查。如果您希望分发调试令牌(例如在 CI 环境中),请参阅此文档,详细了解如何分发。

使用别名填写调试令牌的示例

在 Firebase 控制台中注册调试令牌后,您就可以重新启用 App Check 强制执行,并通过从终端调用 firebase serve 来测试应用内容是否在本地加载。您应该会看到之前输入的数据已提供给本地版本的 Web 应用。您应该仍会看到输出到控制台的包含调试令牌的消息。

在生产环境中试用

确认 App Check 在本地正常运行后,将 Web 应用部署到生产环境。在终端中再次调用 firebase deploy,然后重新加载页面。这会将您的 Web 应用打包,以便在 Firebase Hosting 上运行。应用托管到 Firebase Hosting 后,请尝试通过 ${YOUR_PROJECT_ID}.web.app 访问您的应用。您可以打开 JavaScript 控制台,应该不会再看到其中输出调试令牌,并且应该会看到聊天在项目中加载。此外,在与应用互动片刻后,您可以访问 Firebase 控制台的 App Check 部分,验证对应用的请求是否已全部切换为经过验证。

8. 恭喜!

恭喜,您已成功将 Firebase App Check 添加到 Web 应用中!

您设置了 Firebase 控制台,以便为生产环境处理 reCAPTCHA Enterprise 令牌,甚至还为本地开发设置了调试令牌。这样可以确保您的应用仍然能够从获批的客户端访问 Firebase 资源,并防止应用内发生欺诈活动。

后续操作

请参阅以下文档,了解如何将 Firebase App Check 添加到:

参考文档