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,从而保护聊天应用。

由你精心打造的入门级聊天应用。

学习内容

  • 如何监控后端中是否存在未经授权的访问
  • 如何向 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. 登录 Firebase
  2. 在 Firebase 控制台中,点击“Add Project”(添加项目),然后将您的 Firebase 项目命名为 FreeChat。记住 Firebase 项目的 ID。
  3. 取消选中“为此项目启用 Google Analytics(分析)”
  4. 点击“创建项目”。

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

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

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

将 Firebase Web 应用添加到项目中

  1. 点击 Web 图标 58d6543a156e56f9.png 以创建新的 Firebase Web 应用。
  2. 使用别名“友好聊天”注册应用,然后选中 还要为此应用设置 Firebase Hosting 旁边的复选框,然后点击注册应用
  3. 在下一步中,您将看到一个使用 npm 安装 Firebase 的命令和一个配置对象。您稍后将在此 Codelab 中复制此对象,因此目前,请按 Next

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

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

启用 Google 登录以用于 Firebase 身份验证

为了允许用户使用其 Google 帐号登录 Web 应用,我们将使用 Google 登录方法。

您需要启用 Google 登录:

  1. 在 Firebase 控制台中,找到左侧面板中的构建部分。
  2. 点击身份验证,点击开始使用(如适用),然后点击登录方法标签页(或点击此处直接转到相应页面)。
  3. 启用 Google 登录提供方
  4. 将应用的公开名称设置为 Free Chat,并从下拉菜单中选择项目支持电子邮件地址。
  5. 点击保存

f96888973c3d00cc

启用 Cloud Firestore

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

您需要启用 Cloud Firestore:

  1. 在 Firebase 控制台的构建部分中,点击 Firestore 数据库
  2. 点击 Cloud Firestore 窗格中的创建数据库

Cloud Firestore“创建数据库”按钮

  1. 选择以测试模式开始选项,然后在阅读有关安全规则的免责声明后点击下一步

测试模式可确保您在开发过程中可以随意向数据库写入数据。起始代码中已经为您编写了安全规则。您将在此 Codelab 中使用这些模型。

数据库安全规则窗口。通过

  1. 设置 Cloud Firestore 数据的存储位置。你可以将其保留为默认值,或选择你附近的区域。点击启用以预配 Firestore。

a3d24f9f4ace1917.png

启用 Cloud Storage

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

您需要启用 Cloud Storage:

  1. 在 Firebase 控制台的构建部分中,点击存储
  2. 如果没有开始使用按钮,则表示 Cloud Storage 已启用,您无需按照以下步骤操作。
  3. 点击开始使用
  4. 选择以测试模式开始选项,然后在阅读有关安全规则的免责声明后点击下一步

设置默认安全规则后,任何通过身份验证的用户都可以向 Cloud Storage 写入任何内容。在本 Codelab 的后面部分,我们将部署已经为我们编写的安全规则。

1c875cef812a4384

  1. Cloud Storage 位置已预先选定,以及您为 Cloud Firestore 数据库选择的区域。点击完成以完成设置。

d038569661620910

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.appspot.com",
  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 应用部署到 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 并等待几分钟,让它运行完毕。然后,点击 Enterprise 密钥旁边的创建密钥。然后,在此部分中,指定显示名称并选择网站类型的键。您需要指定托管您的应用的网域。由于您计划在 Firebase Hosting 上托管此配置,因此请使用默认托管名称,通常为 ${YOUR_PROJECT_ID}.web.app。您可以在 Firebase 控制台的“托管”部分下找到您的托管网域。填写这些信息后,依次按完成创建密钥

reCAPTCHA 创建密钥界面

完成后,您会在 Key Details 页面顶部看到一个 ID。

reCAPTCHA 企业注册窗口

接下来,将此 ID 复制到剪贴板。这是您用于 App Check 的密钥。接下来,访问 Firebase 控制台的 App Check 部分,然后点击开始使用。然后依次点击 RegisterreCAPTCHA Enterprise,并将复制的 ID 放入 reCAPTCHA Enterprise 网站密钥对应的文本框中。将其余设置保留为默认值。您的 App Check 页面应如下所示:

用于注册 reCAPTCHA Enterprise 令牌的 App Check 应用窗口

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

现在,您已在 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)的后端服务的请求。返回到应该在 http://localhost:5000 中运行的正在运行的 Web 应用。当您刷新页面并尝试从数据库获取数据时,没有任何反应。如果您打开 Chrome 控制台查看错误,应该会看到类似如下所示的内容:

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

对于未在发送到您的 Firebase 资源的请求中传递有效证明令牌的请求,此 App Check 会屏蔽此类请求。目前,您可以关闭 App Check 强制执行,下一部分将介绍如何将 reCAPTCHA Enterprise App Check 添加到 Relation 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 添加到其中:

参考文档