Apple App Check (適用於 Apple 平台)

1. 簡介

Firebase App Check 可確保要求來自正當的應用程式和裝置,有助於保護後端資源,避免發生帳單詐欺和網路釣魚等濫用行為。這項服務可與 Firebase 服務和您自己的後端服務搭配使用,確保資源安全無虞。

如要進一步瞭解 Firebase App Check,請參閱 Firebase 說明文件。

App Check 會使用平台專用服務,驗證應用程式和/或裝置的完整性。這些服務稱為「認證供應商」。其中一個供應商是 Apple 的 App Attest 服務,App Check 可使用這項服務驗證 Apple 應用程式和裝置的真實性。

建構項目

在本程式碼研究室中,您將在現有的範例應用程式中新增及強制執行應用程式檢查,確保專案的即時資料庫不會遭到非法應用程式和裝置存取。

課程內容

  • 如何將 Firebase App Check 新增至現有應用程式。
  • 如何安裝不同的 Firebase App Check 認證供應商。
  • 如何為應用程式設定 App Attest。
  • 如何在應用程式開發期間設定除錯認證供應商,以便在模擬器上測試應用程式。

軟硬體需求

  • Xcode 13.3.1 以上版本
  • Apple 開發人員帳戶,可供您建立新的應用程式 ID
  • 支援 App Attest 的 iOS/iPadOS 裝置 (請參閱這篇文章,瞭解 App Attest API 的適用情形)

2. 取得範例專案

iOS 適用的 Firebase 快速入門導覽課程存放區包含範例應用程式,可說明不同的 Firebase 產品。您將使用 SwiftUI 適用的 Firebase Database Quickstart 應用程式,做為本程式碼研究室的基礎。

從指令列複製 Firebase iOS 快速入門存放區

git clone https://github.com/firebase/quickstart-ios.git
cd quickstart-ios

在 Xcode 中開啟 Realtime Database SwiftUI Quickstart 應用程式專案:

cd database/DatabaseExampleSwiftUI/DatabaseExample
xed .

3. 在應用程式中加入 App Check

  1. 等待 Swift Package Manager 解決專案的依附元件。
  2. 開啟 DatabaseExample (iOS) 應用程式目標的「一般」分頁。然後在「架構、程式庫和內嵌內容」部分中,按一下「+」按鈕。
  3. 選取「新增」圖示 FirebaseAppCheck

4. 建立及安裝 App Check 提供者 Factory

  1. Shared 檔案群組中,新增名為 AppCheck 的群組。
  2. 在這個群組中,在個別檔案 (例如 MyAppCheckProviderFactory.swift) 中建立工廠類別,並務必將其新增至 DatabaseExample (iOS) 目標:
    import Firebase
    
    class MyAppCheckProviderFactory: NSObject, AppCheckProviderFactory {
      func createProvider(with app: FirebaseApp) -> AppCheckProvider? {
        #if targetEnvironment(simulator)
          // App Attest is not available on simulators.
          // Use a debug provider.
          return AppCheckDebugProvider(app: app)
        #else
          // Use App Attest provider on real devices.
          return AppAttestProvider(app: app)
        #endif
      }
    }
    
  3. 接著,請在 DatabaseExampleApp.swift 中匯入 FirebaseAppCheck,並將 MyAppCheckProviderFactory 類別的例項設為 App Check 提供者工廠。
    import SwiftUI
    import FirebaseCore
    import FirebaseAppCheck
    
    @main
    struct DatabaseExampleApp: App {
      init() {
        // Set an instance of MyAppCheckProviderFactory as an App Check
        // provider factory before configuring Firebase.
        AppCheck.setAppCheckProviderFactory(MyAppCheckProviderFactory())
        FirebaseApp.configure()
      }
      ...
    }
    

5. 建立及設定 Firebase 專案

如要在 iOS 專案中使用 App Check,請在 Firebase 控制台中按照下列步驟操作:

  • 設定 Firebase 專案。
  • 將 iOS 應用程式新增至 Firebase 專案。
  • 設定 Firebase 驗證。
  • 初始化要保護的即時資料庫執行個體。
  • 設定 App Check。

建立專案

首先,您需要建立 Firebase 專案。

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

建立即時資料庫執行個體

接著前往 Firebase 控制台的「Realtime Database」部分。

  1. 按一下「建立資料庫」按鈕,開始建立資料庫。
  2. 將資料庫保留在預設位置 (us-central1),然後按一下「下一步」
  3. 確認已選取「鎖定模式」,然後按一下「啟用」按鈕,為資料庫啟用安全性規則。
  4. 前往即時資料庫瀏覽器的「規則」分頁,然後將預設規則替換為下列規則:
    {
        "rules": {
            // User profiles are only readable/writable by the user who owns it
            "users": {
                "$UID": {
                    ".read": "auth.uid == $UID",
                    ".write": "auth.uid == $UID"
                }
            },
            // Posts can be read by anyone but only written by logged-in users.
            "posts": {
                ".read": true,
                ".write": "auth.uid != null",
                "$POSTID": {
                    // UID must match logged in user and is fixed once set
                    "uid": {
                        ".validate": "(data.exists() && data.val() == newData.val()) || newData.val() == auth.uid"
                    },
                    // User can only update own stars
                    "stars": {
                        "$UID": {
                            ".validate": "auth.uid == $UID"
                        }
                    }
                }
            },
            // User posts can be read by anyone but only written by the user that owns it,
            // and with a matching UID
            "user-posts": {
                ".read": true,
                "$UID": {
                    "$POSTID": {
                        ".write": "auth.uid == $UID",
                        ".validate": "data.exists() || newData.child('uid').val() == auth.uid"
                    }
                }
            },
            // Comments can be read by anyone but only written by a logged in user
            "post-comments": {
                ".read": true,
                ".write": "auth.uid != null",
                "$POSTID": {
                    "$COMMENTID": {
                        // UID must match logged in user and is fixed once set
                        "uid": {
                            ".validate": "(data.exists() && data.val() == newData.val()) || newData.val() == auth.uid"
                        }
                    }
                }
            }
        }
    }
    
  5. 按一下「發布」按鈕,啟用更新後的安全性規則。

準備將 iOS 應用程式連結至 Firebase

如要在實體裝置上執行範例應用程式,您必須將專案新增至開發團隊,Xcode 才能為您管理必要的佈建設定檔。請按照下列步驟,將範例應用程式新增至開發人員帳戶:

  1. 在 Xcode 中,選取專案導覽器中的 DatabaseExample 專案。
  2. 選取DatabaseExample (iOS)目標,然後開啟「簽署與功能」分頁。
  3. 您應該會看到「Signing for DatabaseExample (iOS) requires a development team」(簽署 DatabaseExample (iOS) 需要開發團隊) 錯誤訊息。
  4. 套件 ID更新為專屬 ID。最簡單的方法是使用網站的反向網域名稱,例如 com.acme.samples.firebase.quickstart.DatabaseExample (請勿使用這個 ID,請改為選擇專屬的 ID)。
  5. 選取開發團隊。
  6. 如果 Xcode 顯示「Provisioning Profile: Xcode Managed Profile」,且這個標籤旁有小資訊圖示,就表示一切順利。按一下這個圖示,即可顯示佈建設定檔的詳細資料。

連結 iOS 應用程式

如要深入瞭解如何連結應用程式,請參閱將 Firebase 新增至 iOS 專案的說明文件。如要開始使用,請在 Firebase 控制台中按照下列主要步驟操作:

  1. 在新的專案的「專案總覽」畫面中,按一下「+ 新增應用程式」按鈕,然後按一下「iOS+」圖示,將新的 iOS 應用程式新增至 Firebase 專案。
  2. 輸入應用程式的軟體包 ID (使用您在上一節中定義的 ID,例如 com.acme.samples.firebase.quickstart.DatabaseExample - 請注意,這個 ID「必須」是專屬 ID)
  3. 按一下「註冊應用程式」
  4. Firebase 會產生 GoogleService-Info.plist 檔案,其中包含應用程式所需的所有 Firebase 中繼資料。
  5. 按一下「Download GoogleService-Info.plist」下載檔案。
  6. 在 Xcode 中,您會看到專案已包含名為 GoogleService-Info.plist 的檔案。請先刪除這個檔案,因為您會在下一個步驟中,將其替換為您自己 Firebase 專案的檔案。
  7. 將上一個步驟下載的 GoogleService-Info.plist 檔案複製到 Xcode 專案的根資料夾,然後新增至 DatabaseExample (iOS) 目標,並確認檔案名稱為 GoogleService-Info.plist
  8. 點選註冊流程的其餘步驟。由於範例專案已正確設定,因此您不需要變更任何程式碼。

設定 Firebase 驗證

大功告成!目前為止的設定相當多,但請稍安勿躁!如果您剛接觸 Firebase,您已瞭解工作流程的重要部分,很快就能熟悉這些內容。

現在,您要為這個應用程式設定 Firebase 驗證。

啟用「Authentication Email/Password Sign-in provider」(驗證電子郵件地址/密碼登入提供者)

  1. Firebase 控制台中,開啟控制台的「驗證」部分。
  2. 按一下「開始使用」,為專案設定 Firebase 驗證。
  3. 選取「登入方式」分頁標籤。
  4. 在「原生供應商」部分中,選取「電子郵件/密碼」
  5. 啟用「電子郵件/密碼」,然後按一下「儲存」

新增測試使用者

  1. 開啟「驗證」部分的「使用者」分頁。
  2. 點選「Add user」
  3. 指定測試使用者的電子郵件和密碼,然後按一下「新增使用者」

試用應用程式

返回 Xcode,在 iOS 模擬器上執行應用程式。使用您剛建立的測試使用者電子郵件地址和密碼登入。登入後,即可建立貼文、在現有貼文中留言,以及為貼文加上/取消加上星號。

6. 設定 App Attest 認證供應商

在這個步驟中,您將在 Firebase 控制台中設定 App Check,以使用 App Attest 供應商。

  1. 在 Firebase 控制台中,前往控制台的「App Check」部分。
  2. 按一下「開始使用」
  3. 在「應用程式」分頁中,按一下應用程式即可展開詳細資料。
  4. 按一下「App Attest」設定 App Attest,然後輸入 Apple 開發人員帳戶的團隊 ID (您可以在 Apple 開發人員入口網站的「Membership」部分找到這個 ID):1645f7a369b678c2.png
  5. 按一下 [儲存]

這樣一來,您就有一個可用的 Firebase 專案,並連結至新應用程式,且已啟用應用程式檢查。

您現在可以設定專屬的認證服務了!如要進一步瞭解這個工作流程,請參閱「在 iOS 裝置上使用 App Attest 啟用 App Check」。

7. 為應用程式設定 App Attest

現在請開始使用 Firebase App Check SDK,並導入一些用戶端程式碼。

首先,您需要設定 Xcode 專案,讓 SDK 可以使用 Apple 的 App Attest API,確保應用程式傳送的要求來自應用程式的合法例項。

  1. 在 Xcode 專案中,為應用程式目標新增 App Attest 功能:
  2. 在應用程式目標設定中開啟「簽署和功能」分頁
  3. 按一下「+」按鈕
  4. 在對話方塊中,找出並選取「App Attest」功能 ae84cd988a5fab31.png
  5. 執行上一個步驟後,Xcode 專案的根資料夾中會顯示 DatabaseExample (iOS).entitlements 檔案。
  6. DatabaseExample (iOS).entitlements 檔案中,將 App Attest Environment 鍵的值變更為 production.

完成上述步驟並在實體 iOS 裝置 (iPhone/iPad) 上啟動應用程式後,應用程式仍可存取 Realtime Database。在後續步驟中,您將強制執行 App Check,封鎖來自非法應用程式和裝置的要求。

如要進一步瞭解這個工作流程,請參閱「在 iOS 裝置上使用 App Attest 啟用 App Check」。

8. 為 iOS 模擬器設定 Debug Attestation Provider

開發期間,您可以使用 Firebase App Check 偵錯供應商,在不受信任的環境 (包括 iOS 模擬器) 中,測試強制執行 Firebase App Check 的應用程式。接下來,您需要一起設定偵錯供應商。

在應用程式中安裝 Firebase 偵錯供應商

選項 1:在工廠中,有條件地建立偵錯供應器的執行個體

您在建立 App Check 提供者工廠時,已完成大部分步驟。在這個步驟中,您將新增偵錯供應商產生的本機偵錯密鑰記錄,以便在 Firebase 控制台中註冊這個應用程式執行個體,用於偵錯。

使用下列程式碼更新 MyAppCheckProviderFactory.swift

import Firebase

class MyAppCheckProviderFactory: NSObject, AppCheckProviderFactory {
  func createProvider(with app: FirebaseApp) -> AppCheckProvider? {
#if targetEnvironment(simulator)
    // App Attest is not available on simulators.
    // Use a debug provider.
    let provider = AppCheckDebugProvider(app: app)

    // Print only locally generated token to avoid a valid token leak on CI.
    print("Firebase App Check debug token: \(provider?.localDebugToken() ?? "" )")

    return provider
#else
    // Use App Attest provider on real devices.
    return AppAttestProvider(app: app)
#endif
  }
}

這個做法可讓我們根據環境,更彈性地設定 App Check。舉例來說,在不支援 App Attest 的 OS 版本上,您可以使用其他認證提供者,例如 DeviceCheck 或自訂認證提供者。請參閱以下範例:

import Firebase

class MyAppCheckProviderFactory: NSObject, AppCheckProviderFactory {
  func createProvider(with app: FirebaseApp) -> AppCheckProvider? {
      #if targetEnvironment(simulator)
      // App Attest is not available on simulators.
      // Use a debug provider.
      let provider = AppCheckDebugProvider(app: app)

      // Print only locally generated token to avoid a valid token leak on CI.
      print("Firebase App Check debug token: \(provider?.localDebugToken() ?? "" )")

      return provider
      #else
      if #available(iOS 14.0, *) {
        // Use App Attest provider on real devices.
        return AppAttestProvider(app: app)
      } else {
        return DeviceCheckProvider(app: app)
      }
      #endif
  }
}

選項 2:安裝 AppCheckDebugProviderFactory

如果是較簡單的情況,您可以暫時或有條件地安裝 AppCheckDebugProviderFactory,再設定 Firebase 應用程式例項:

init() {
#if targetEnvironment(simulator)
  let providerFactory = AppCheckDebugProviderFactory()
#else
  let providerFactory = MyAppCheckProviderFactory()
#endif

  AppCheck.setAppCheckProviderFactory(providerFactory)

  FirebaseApp.configure()
}

這樣一來,您在建立自己的 App Check 提供者工廠時,就能省下幾行程式碼。

在 Firebase 控制台中註冊偵錯密鑰

從 iOS 模擬器取得偵錯密鑰

  1. 如果您選擇安裝 AppCheckDebugProviderFactory (上述選項 2),請將 -FIRDebugEnabled 新增至應用程式啟動引數,為應用程式啟用偵錯記錄:f1c6b477a373e144.png
  2. 在模擬器上執行應用程式
  3. 在 Xcode 控制台中找出偵錯密鑰。您可以使用控制台篩選器,更快找到該項目:d4c65af93e369c55.png

注意:偵錯密鑰會在首次啟動應用程式時為模擬器產生,並儲存在使用者預設值中。如果移除應用程式、重設模擬器或使用其他模擬器,系統會產生新的偵錯密鑰。請務必註冊新的偵錯密鑰。

註冊偵錯密鑰

  1. 返回 Firebase 控制台,前往「App Check」部分。
  2. 在「應用程式」分頁中,按一下應用程式即可展開詳細資料。
  3. 在溢位選單中,選取「管理偵錯權杖」d77c8ff768a00b4b.png
  4. 新增從 Xcode 控制台複製的密鑰,然後按一下「儲存」圖示 f845c97b86f694d0.png

完成這些步驟後,即使強制執行 App Check,您仍可在模擬器上使用應用程式。

注意:偵錯供應商的設計宗旨是防止偵錯密鑰外洩。使用目前的方法,您不需要在原始碼中儲存偵錯密鑰。

如要進一步瞭解這個流程,請參閱「在 iOS 上搭配偵錯供應器使用應用程式檢查」一文。

9. 為 Firebase 即時資料庫啟用 App Check 強制執行功能

目前,我們的應用程式會宣告 AppCheckProviderFactory,針對實際裝置傳回 AppAttestProvider。在實體裝置上執行時,應用程式會執行認證,並將結果傳送至 Firebase 後端。不過,Firebase 後端仍會接受來自任何裝置、iOS 模擬器、指令碼等的請求。如果您的應用程式仍有舊版使用者,且您還不想強制執行存取檢查,這個模式就非常實用。

現在,您需要啟用 App Check 強制執行,確保只有正當裝置可以存取 Firebase 應用程式。一旦為 Firebase 專案啟用強制執行功能,未整合 App Check 的舊版應用程式就會停止運作。

  1. 在 Firebase 控制台的「App Check」部分,按一下「Realtime Database」展開詳細資料。
  2. 按一下「強制執行」

64e6a81fa979b635.png

  1. 詳閱確認對話方塊中的資訊,然後按一下「強制執行」

完成這些步驟後,只有正當應用程式才能存取資料庫。其他應用程式都會遭到封鎖。

嘗試使用非法應用程式存取 Realtime Database

如要查看應用程式檢查強制執行作業,請按照下列步驟操作:

  1. 如要停用 App Check 註冊功能,請在 DatabaseExampleApp 中應用程式進入點的 init 方法中,註解掉 App Check 註冊程式碼。
  2. 依序選取「Device」>「Erase All Content and Settings」,重設模擬器。這會清除模擬器 (並使裝置權杖失效)。
  3. 再次在模擬器上執行應用程式。
  4. 您現在應該會看到下列錯誤訊息:
    [FirebaseDatabase][I-RDB034005] Firebase Database connection was forcefully killed by the server.  Will not attempt reconnect. Reason: Invalid appcheck token.
    

如要重新啟用應用程式檢查,請按照下列步驟操作:

  1. DatabaseExampleApp 中取消註解 App Check 註冊程式碼。
  2. 重新啟動應用程式。
  3. 記下 Xcode 控制台中的新 App Check 權杖。
  4. 在 Firebase 控制台中,於應用程式的 App Check 設定中註冊偵錯權杖。
  5. 重新執行應用程式。
  6. 您應該不會再看到錯誤訊息,而且可以在應用程式中新增貼文和留言。

10. 恭喜!

9785d32f18b995d2.gif

您現在已瞭解如何:

  • 將 App Check 新增至現有專案
  • 為應用程式正式版設定 App Attest 認證供應商
  • 設定偵錯認證供應商,在模擬器上測試應用程式
  • 觀察應用程式版本推出情形,瞭解何時為 Firebase 專案強制執行 App Check
  • 啟用 App Check 強制執行功能

後續步驟

請參閱「使用 Firebase 遠端設定逐步推出 Firebase App Check Codelab」,瞭解如何使用遠端設定,逐步向使用者推出 App Check。

其他實用資源

本程式碼研究室中說明的設定適用於大多數情況,但如果需要更多彈性,您可以改用 App Check。詳情請參閱下列連結: