App Check 網站程式碼研究室

1. 簡介

上次更新時間:2023 年 2 月 23 日

如何防止未經授權存取 Firebase 資源?

您可以使用 Firebase App Check,要求傳入的要求必須附上證明,確認要求來自您的真實應用程式,並封鎖沒有適當證明的流量,防止未經授權的用戶端存取後端資源。Firebase App Check 仰賴平台專屬的認證供應商驗證用戶端真實性:針對網頁應用程式,App Check 支援 reCAPTCHA v3 和 reCAPTCHA Enterprise 做為認證供應商。

App Check 可用於保護傳送至 Cloud Firestore、即時資料庫、Cloud Functions、Firebase 驗證 with Identity Platform,以及您自行託管後端的要求。

建構項目

在本程式碼研究室中,您將先新增 App Check,然後強制執行,藉此保護即時通訊應用程式。

您建構的 Friendly Chat 應用程式。

課程內容

  • 如何監控後端,防止未經授權的存取
  • 如何對 Firestore 和 Cloud Storage 實施強制執行
  • 如何使用偵錯權杖執行應用程式,以便在本機開發

軟硬體需求

  • 您選擇的 IDE/文字編輯器
  • 套件管理工具 npm,通常隨附於 Node.js
  • 已安裝 Firebase CLI,並設定為與您的帳戶搭配使用
  • 終端機/控制台
  • 你選擇的瀏覽器,例如 Chrome
  • 程式碼實驗室的程式碼範例 (請參閱程式碼實驗室的下一個步驟,瞭解如何取得程式碼)。

2. 取得程式碼範例

從指令列複製程式碼實驗室的 GitHub 存放區:

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

或者,如果您未安裝 Git,可以將存放區下載為 ZIP 檔案。

匯入範例應用程式

使用 IDE,從複製的存放區開啟或匯入 📁 appcheck-start 目錄。這個 📁 appcheck-start 目錄包含程式碼實驗室的範例程式碼,這會是功能完整的即時通訊網頁應用程式。📁 appcheck 目錄則包含程式碼實驗室的完整程式碼。

3. 建立及設定 Firebase 專案

建立 Firebase 專案

  1. 使用 Google 帳戶登入 Firebase 控制台。
  2. 按一下按鈕建立新專案,然後輸入專案名稱 (例如 FriendlyChat)。
  3. 按一下「繼續」。
  4. 如果出現提示訊息,請詳閱並接受 Firebase 條款,然後點選「繼續」。
  5. (選用) 在 Firebase 控制台中啟用 AI 輔助功能 (稱為「Gemini in Firebase」)。
  6. 在本程式碼實驗室中,您不需要 Google Analytics,因此請關閉 Google Analytics 選項。
  7. 按一下「Create project」,等待專案佈建完成,然後點選「Continue」。

升級 Firebase 定價方案

如要使用 Cloud Storage for Firebase,Firebase 專案必須採用即付即用 (Blaze) 定價方案,也就是連結至 Cloud Billing 帳戶。

  • Cloud Billing 帳戶必須設定付款方式,例如信用卡。
  • 如果您剛開始使用 Firebase 和 Google Cloud,請確認是否符合 $300 美元抵免額和免費試用 Cloud Billing 帳戶的資格。
  • 如果您是參加活動而進行這個程式碼實驗室,請詢問主辦單位是否有可用的 Cloud 抵免額。

如要將專案升級至 Blaze 方案,請按照下列步驟操作:

  1. 在 Firebase 控制台中,選取「升級方案」。
  2. 選取 Blaze 方案。按照畫面上的指示,將 Cloud Billing 帳戶連結至專案。
    如果需要建立 Cloud Billing 帳戶才能完成升級,你可能要返回 Firebase 控制台的升級流程,才能完成升級。

在專案中新增 Firebase 網頁應用程式

  1. 按一下網頁圖示 58d6543a156e56f9.png,建立新的 Firebase 網頁應用程式。
  2. 使用暱稱「Friendly Chat」註冊應用程式,然後勾選「一併為這個應用程式設定 Firebase 託管」旁的方塊,再點選「註冊應用程式」。
  3. 在下一個步驟中,您會看到使用 npm 安裝 Firebase 的指令和設定物件。您會在程式碼實驗室稍後步驟複製這個物件,因此請先點選「Next」。

「將 Firebase 新增至網頁應用程式」視窗

  1. 接著,您會看到安裝 Firebase CLI 的選項。如果尚未安裝,請立即使用 npm install -g firebase-tools 指令安裝。然後點按「下一步」。
  2. 接著,您會看到登入 Firebase 並部署至 Firebase 託管的選項。請使用 firebase login 指令登入 Firebase,然後點選「前往控制台」。您會在後續步驟中部署至 Firebase 託管。

設定 Firebase 產品

我們要建構的應用程式會使用幾項 Firebase 產品,這些產品都可用於網頁應用程式:

  • Firebase 驗證:可讓使用者輕鬆登入您的應用程式。
  • Cloud Firestore:將結構化資料儲存在雲端,並在資料變更時立即收到通知。
  • Cloud Storage for Firebase:將檔案儲存至雲端。
  • Firebase 託管:託管及提供資產。
  • Firebase 雲端通訊:傳送推播通知及顯示瀏覽器彈出式通知。
  • Firebase Performance Monitoring:收集應用程式的使用者成效資料。

部分產品需要特殊設定或透過 Firebase 控制台啟用。

為 Firebase 驗證啟用 Google 登入

為了讓使用者以 Google 帳戶登入網頁應用程式,我們將使用 Google 登入方式。

您必須啟用 Google 登入功能:

  1. 在 Firebase 控制台的左側面板中,找到「Build」部分。
  2. 依序點選「Authentication」和「Get Started」(如有),然後點選「登入方式」分頁標籤 (或按這裡直接前往)。
  3. 啟用 Google 登入提供者
  4. 將應用程式的公開名稱設為「Friendly Chat」,並從下拉式選單中選擇專案支援電子郵件地址。
  5. 按一下「儲存」。

f96888973c3d00cc.png

設定 Cloud Firestore

網頁應用程式會使用 Cloud Firestore 儲存即時通訊訊息,並接收新的即時通訊訊息。

在 Firebase 專案中設定 Cloud Firestore 的方法如下:

  1. 在 Firebase 控制台的左側面板中,展開「Build」,然後選取「Firestore 資料庫」。
  2. 按一下 [Create database] (建立資料庫)。
  3. 將「資料庫 ID」保留為 (default)。
  4. 選取資料庫的位置,然後點選「下一步」。
    如果是實際應用程式,建議選擇靠近使用者的位置。
  5. 按一下「Start in test mode」(以測試模式啟動)。請詳閱安全性規則免責事項。
    在本程式碼實驗室的後續步驟中,您將新增安全性規則來保護資料。請勿在未新增資料庫安全性規則的情況下,公開發布或公開應用程式。
  6. 點選「建立」。

設定 Cloud Storage for Firebase

網頁應用程式會使用 Cloud Storage for Firebase 儲存、上傳及分享圖片。

在 Firebase 專案中設定 Cloud Storage for Firebase 的方法如下:

  1. 在 Firebase 控制台的左側面板中,展開「Build」,然後選取「Storage」。
  2. 按一下「開始使用」。
  3. 選取預設 Storage bucket 的位置。
    US-WEST1、US-CENTRAL1 和 US-EAST1 中的 bucket 可享有 Google Cloud Storage 的「一律免費」級別。所有其他位置的值區則遵循 Google Cloud Storage 定價和用量。
  4. 按一下「Start in test mode」(以測試模式啟動)。請詳閱安全性規則免責事項。
    在本程式碼實驗室的後續步驟中,您將新增安全性規則來保護資料。請勿在未新增 Storage bucket 安全性規則的情況下,公開發布或公開應用程式。
  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。本程式碼實驗室的其餘部分假設變數名稱為 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

這會啟用網頁框架支援,也就是建構這項專案時使用的框架。

現在應該可以執行專案,並測試預設專案是否正常運作!

5. 在不使用 App Check 的情況下試用應用程式

現在您已設定好應用程式和 SDK,請嘗試按照原先設計使用應用程式。首先,請安裝所有依附元件。在終端機中前往 appcheck-start/hosting 目錄。在該目錄中執行 npm install。這會擷取專案運作所需的所有依附元件。如要以目前狀態啟動應用程式,您可以執行 firebase serve。應用程式會要求您使用 Google 帳戶登入。請登入帳戶,然後嘗試在即時通訊中張貼幾則即時通訊訊息和相片。

在本機測試完畢後,就可以在正式環境中查看了!執行 firebase deploy,將網頁應用程式部署至網路。這個部分是示範 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 託管上託管這個應用程式,因此請使用預設主機名稱,通常是 ${YOUR_PROJECT_ID}.web.app。您可以在 Firebase 控制台的「Hosting」部分找到託管網域。填寫完畢後,請依序按下「完成」和「建立金鑰」。

reCAPTCHA 建立金鑰畫面

完成後,「Key Details」(金鑰詳細資料) 頁面頂端會顯示 ID。

reCAPTCHA Enterprise 註冊視窗

請將這個 ID 複製到剪貼簿。這是您用於 App Check 的金鑰。接著,前往 Firebase 控制台的「App Check」部分,然後按一下「開始使用」。接著,依序點選「註冊」和「reCAPTCHA Enterprise」,然後將複製的 ID 貼到「reCAPTCHA Enterprise 網站金鑰」文字方塊。其餘設定則保留預設值。App Check 頁面應如下所示:

App Check 應用程式視窗,您可以在此註冊 reCAPTCHA Enterprise 權杖

未經驗證和未強制執行的要求

在 Firebase 控制台註冊金鑰後,請執行 firebase serve,返回瀏覽器執行網站。現在網頁應用程式已在本機執行,您可以再次開始向 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 執行)。重新整理頁面並嘗試從資料庫取得資料時,系統不會執行任何動作。如果開啟 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,測試應用程式內容是否在本機載入。您應該會看到先前輸入的資料,已提供給本機版本的網頁應用程式。您應該仍會看到控制台顯示偵錯權杖訊息。

在正式環境中試用

確認 App Check 在本機運作正常後,即可將網頁應用程式部署至正式環境。再次從終端機呼叫 firebase deploy,然後重新載入頁面。這項操作會將網頁應用程式封裝,以便在 Firebase 託管上執行。應用程式託管於 Firebase 託管後,請嘗試前往 ${YOUR_PROJECT_ID}.web.app 存取應用程式。開啟 JavaScript 控制台後,應該不會再看到偵錯權杖,而是會看到專案中載入的對話。此外,與應用程式互動一段時間後,您可以前往 Firebase 控制台的「App Check」部分,確認傳送至應用程式的要求是否都已切換為「已驗證」。

8. 恭喜!

恭喜,您已成功將 Firebase App Check 新增至網頁應用程式!

您在 Firebase 控制台設定了正式環境的 reCAPTCHA Enterprise 權杖,甚至為本機開發環境設定了偵錯權杖。這可確保應用程式仍能從核准的用戶端存取 Firebase 資源,並防止應用程式內發生詐欺活動。

後續步驟

請參閱下列說明文件,瞭解如何將 Firebase App Check 新增至:

參考文件