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 项目
- 使用您的 Google 账号登录 Firebase 控制台。
- 点击相应按钮以创建新项目,然后输入项目名称(例如
FriendlyChat
)。
- 点击继续。
- 如果看到相关提示,请查看并接受 Firebase 条款,然后点击继续。
- (可选)在 Firebase 控制台中启用 AI 辅助功能(称为“Gemini in Firebase”)。
- 在此 Codelab 中,您不需要使用 Google Analytics,因此请关闭 Google Analytics 选项。
- 点击创建项目,等待项目完成预配,然后点击继续。
升级您的 Firebase 定价方案
如需使用 Cloud Storage for Firebase,您的 Firebase 项目必须采用随用随付 (Blaze) 定价方案,这意味着该项目与一个 Cloud Billing 账号相关联。
- Cloud Billing 账号要求提供付款方式,例如信用卡。
- 如果您刚开始接触 Firebase 和 Google Cloud,请确认您是否有资格获得 $300 赠金和免费试用 Cloud Billing 账号。
- 如果您是在活动中完成此 Codelab,请询问活动组织者是否有可用的 Cloud 积分。
如需将项目升级到 Blaze 方案,请按以下步骤操作:
- 在 Firebase 控制台中,选择升级您的方案。
- 选择 Blaze 方案。按照屏幕上的说明将 Cloud Billing 账号与您的项目相关联。
如果您需要在此升级过程中创建 Cloud Billing 账号,则可能需要返回 Firebase 控制台中的升级流程以完成升级。
向项目添加 Firebase Web 应用
- 点击 Web 图标
以创建新的 Firebase Web 应用。
- 注册昵称为 Friendly Chat 的应用,然后选中还为此应用设置 Firebase Hosting 旁边的复选框。点击注册应用。
- 在下一步中,您将看到使用 npm 安装 Firebase 的命令和一个配置对象。您将在本 Codelab 的后半部分复制此对象,因此现在请按下一步。
- 然后,您会看到安装 Firebase CLI 的选项。如果您尚未安装,请立即使用命令
npm install -g firebase-tools
进行安装。然后点击下一步。 - 然后,您会看到一个用于登录 Firebase 并部署到 Firebase 托管的选项。继续操作,使用命令
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 登录:
- 在 Firebase 控制台中,在左侧面板中找到构建部分。
- 点击身份验证,点击开始(如果适用),然后点击登录方法标签页(或点击此处直接转到该标签页)。
- 启用 Google 登录提供方
- 将应用的公开名称设置为 Friendly Chat,然后从下拉菜单中选择项目支持电子邮件地址。
- 点击保存
设置 Cloud Firestore
Web 应用使用 Cloud Firestore 保存聊天消息并接收新的聊天消息。
以下是在 Firebase 项目中设置 Cloud Firestore 的方法:
- 在 Firebase 控制台的左侧面板中,展开构建,然后选择 Firestore 数据库。
- 点击创建数据库。
- 将数据库 ID 保留为
(default)
。 - 为数据库选择一个位置,然后点击下一步。
对于真实应用,您需要选择靠近用户的位置。 - 点击以测试模式开始。阅读有关安全规则的免责声明。
在本 Codelab 的后面部分,您将添加安全规则来保护您的数据。在没有为数据库添加安全规则的情况下,请不要公开分发或公开应用。 - 点击创建。
设置 Cloud Storage for Firebase
该 Web 应用使用 Cloud Storage for Firebase 来存储、上传和分享图片。
以下是在 Firebase 项目中设置 Cloud Storage for Firebase 的方法:
- 在 Firebase 控制台的左侧面板中,展开构建,然后选择存储。
- 点击开始使用。
- 为默认存储分区选择位置。
US-WEST1
、US-CENTRAL1
和US-EAST1
中的存储分区可为 Google Cloud Storage 使用“始终免费”层级。所有其他位置的存储分区都遵循 Google Cloud Storage 价格和用量。 - 点击以测试模式开始。阅读有关安全规则的免责声明。
在本 Codelab 的后面部分,您将添加安全规则来保护您的数据。在未为您的存储桶添加安全规则的情况下,请不要公开分发或公开应用。 - 点击创建。
4. 配置 Firebase
从 appcheck-start
目录中,调用:
firebase use --add
当系统提示时,选择您的项目 ID,然后为您的 Firebase 项目指定一个别名。对于此项目,您只需提供别名 default。接下来,您需要配置本地项目以使用 Firebase。
- 前往 Firebase 控制台中的项目设置
- 在“您的应用”卡片中,选择您需要为其添加配置对象的应用的昵称。
- 从 Firebase SDK 代码段窗格中选择 Config。
- 复制配置对象代码段,然后将其添加到
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 控制台的托管部分下找到您的托管网域。填写完这些信息后,按完成和创建密钥。
完成后,您会在关键详情页面顶部看到一个 ID。
接下来,将此 ID 复制到剪贴板。这是您用于 App Check 的密钥。接下来,前往 Firebase 控制台的 App Check 部分,然后点击开始。然后,依次点击注册和 reCAPTCHA Enterprise,并将复制的 ID 放入 reCAPTCHA Enterprise 网站密钥的文本框中。将其余设置保留为默认值。您的 App Check 页面应如下所示:
未验证且未强制执行的请求
现在,您已在 Firebase 控制台中注册密钥,请通过运行 firebase serve
重新在浏览器中运行您的网站。现在,您可以在本地运行 Web 应用,并再次开始针对 Firebase 后端发出请求。由于请求是针对 Firebase 后端的,因此 App Check 会监控这些请求,但不会强制执行。如果您想查看传入请求的状态,可以访问 Firebase 控制台中 App Check 页面的 API 标签页中的 Cloud Firestore 部分。由于您尚未配置客户端以使用 App Check,因此您应该会看到类似以下内容的输出:
后端收到的请求 100% 未经过验证。此界面非常有用,因为它显示几乎所有客户端请求都来自未集成 App Check 的客户端。
此信息中心可显示以下几项内容。首先,它可以指示所有客户端应用是否都在运行最新版本的客户端。如果它们是,那么您可以放心地强制执行 App Check,而不必担心会关闭应用的真实客户端的访问权限。此指标可能还会显示有多少次尝试访问您的后端不是来自您的应用。这可能意味着有用户在您不知情的情况下直接查询您的后端。既然您可以看到请求未经过验证,那么在继续验证这些用户的请求之前,不妨先看看如果这些用户向您的后端发送了未经验证的请求,会发生什么情况。
未验证且已强制执行的请求
继续操作,按上一个界面中的 Enforce 按钮,然后在系统提示时再次按 Enforce。
这会开始强制执行 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 配置中。
为令牌指定一个便于您记住的唯一名称,然后点击保存。此选项允许您在应用中使用客户端生成的令牌,这是一种比生成调试令牌并将其嵌入应用中更安全的替代方案。在应用中嵌入令牌可能会导致令牌意外分发给最终用户,而这些最终用户可能会利用该令牌绕过您的检查。如果您希望在 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 添加到以下平台,请查看以下文档: