Apple App Check (適用於 Apple 平台)

1. 簡介

Firebase App Check 能確保要求來自合法應用程式和裝置,避免後端資源遭到濫用 (例如帳單詐欺和網路釣魚)。這項工具可與 Firebase 服務和您的後端服務搭配運作,確保資源安全無虞。

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

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

建構項目

在這個程式碼研究室中,您要在現有的範例應用程式中新增並強制執行 App Check,讓非法應用程式和裝置無法存取專案的即時資料庫。

課程內容

  • 如何將 Firebase App Check 新增至現有應用程式。
  • 如何安裝其他 Firebase App Check 認證供應商。
  • 如何設定應用程式的 App Attest。
  • 如何設定偵錯認證提供者,以便在應用程式開發期間透過模擬器測試應用程式。

軟硬體需求

  • Xcode 13.3.1 以上版本
  • 可用於建立新應用程式 ID 的 Apple 開發人員帳戶
  • 支援 App Attest 的 iOS/iPadOS 裝置 (請參閱 App Attest API 可用性)

2. 取得範例專案

iOS 適用的 Firebase 快速入門導覽課程包含範例應用程式,可展示各種 Firebase 產品。您將使用 SwiftUI 的 Firebase 資料庫快速入門導覽課程應用程式做為本程式碼研究室的基礎。

從指令列複製 iOS 存放區適用的 Firebase 快速入門導覽課程

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

在 Xcode 中開啟即時資料庫 SwiftUI 快速入門導覽課程應用程式專案:

cd database/DatabaseExampleSwiftUI/DatabaseExample
xed .

3. 在應用程式中新增 App Check

  1. 等待 Swift Package Manager 解析專案的依附元件。
  2. 開啟 DatabaseExample (iOS) 應用程式目標的「一般」分頁。接著,按一下「Frameworks、Library and Embedded Content」部分的「+」按鈕。
  3. 選取即可新增「FirebaseAppCheck」。

4. 建立及安裝 App Check 供應商工廠

  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 專案。
  • 在 Firebase 專案中新增 iOS 應用程式。
  • 設定 Firebase 驗證。
  • 初始化要保護的即時資料庫執行個體。
  • 設定 App Check。

建立專案

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

  1. Firebase 控制台,選取「新增專案」
  2. 為專案「App Check Codelab」命名
  3. 按一下「繼續」
  4. 停用這項專案的 Google Analytics,然後按一下「建立專案」

建立即時資料庫執行個體

接著,前往 Firebase 控制台的「即時資料庫」專區。

  1. 按一下「建立資料庫」按鈕,啟動資料庫建立工作流程。
  2. 保留資料庫的預設位置 (us-central1),然後按一下「Next」
  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. 按一下「Publish」按鈕,啟用更新後的安全性規則。

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

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

  1. 在 Xcode 中的專案導覽工具中選取 DatabaseExample 專案。
  2. 選取 DatabaseExample (iOS) 目標,然後開啟 Signing &功能分頁。
  3. 系統應會顯示錯誤訊息:「Signing for DatabaseExample (iOS) requires a 開發團隊」
  4. 軟體包 ID 更新為不重複的 ID。最簡單的方法就是使用網站的反向網域名稱,例如 com.acme.samples.firebase.quickstart.DatabaseExample (請勿使用這個 ID,而是自己的專屬 ID)。
  5. 選取您的開發團隊。
  6. Xcode 顯示「佈建設定檔:Xcode 受管理的設定檔」時,表示一切運作正常這個標籤旁有一個小資訊圖示按一下這個圖示即可查看佈建設定檔的更多詳細資料。

連結 iOS 應用程式

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

  1. 在新專案的「專案總覽畫面中,按一下「+ 新增應用程式」按鈕,然後點選「iOS+」圖示,在 Firebase 專案中新增 iOS 應用程式。
  2. 輸入應用程式的軟體包 ID (請使用您在上一節定義的 ID,例如 com.acme.samples.firebase.quickstart.DatabaseExample;請注意,這必須是專屬 ID)
  3. 按一下「Register App」
  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 驗證。

啟用驗證電子郵件/密碼登入服務供應商

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

新增測試使用者

  1. 開啟「Authentication」部分的「Users」分頁。
  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 Developer 入口網站的「成員」部分找到這項資訊):1645f7a369b678c2.png
  5. 按一下 [儲存]

使用這項解決方案時,您的 Firebase 專案已連結至新應用程式,且 App Check 已啟用。

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

7. 為應用程式設定 App Attest

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

首先,您必須設定 Xcode 專案,讓 SDK 使用 Apple 的 App Attest API,確保從您應用程式發出的要求,確實來自應用程式的合法執行個體。

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

完成上述步驟並在實體 iOS 裝置 (iPhone/iPad) 上啟動該應用程式後,應用程式仍可存取即時資料庫。在後續步驟中,您將強制執行 App Check,禁止來自非法應用程式和裝置發出的要求。

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

8. 設定 iOS 模擬器的偵錯認證提供者

透過 Firebase App Check Debug 供應商,您可以在開發過程中,在不受信任的環境 (包括 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. 返回 Firevbase 主控台,前往「App Check」App Check 部分。
  2. 在「應用程式」分頁中,按一下所需應用程式即可展開詳細資料。
  3. 在溢位選單中,選取「Manage debug token」d77c8ff768a00b4b.png
  4. 新增您從 Xcode 主控台複製的密鑰,然後按一下「儲存」 圖示 f845c97b86f694d0.png

完成上述步驟後,即使強制執行 App Check,還是可以在模擬器中使用應用程式。

注意:偵錯供應商是專為避免偵錯密鑰外洩而設計。如果採用目前的做法,您就不需要將偵錯密鑰儲存在原始碼中,

如要進一步瞭解這個流程,請參閱說明文件:在 iOS 上透過偵錯供應商使用 App Check

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

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

現在,您必須啟用 App Check 的強制執行功能,確保使用者只能透過合法裝置存取 Firebase 應用程式。為 Firebase 專案啟用強制執行設定後,未整合 App Check 的舊版應用程式版本就會停止運作。

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

64e6a81fa979b635.png

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

完成這些步驟後,只有符合規定的應用程式才能存取資料庫。系統會封鎖所有其他應用程式。

嘗試透過非法應用程式存取即時資料庫

如要查看實際執行 App Check 的方式,請按照下列步驟操作:

  1. DatabaseExampleApp 中,在應用程式進入點的 init 方法中註解 App Check 註冊代碼,即可關閉 App Check 註冊功能。
  2. 依序選取「Device」> 重設模擬器清除所有內容和設定。這麼做會抹除模擬器,並使裝置權杖失效。
  3. 在模擬器上再次執行應用程式。
  4. 您應該會看到以下錯誤訊息:
    [FirebaseDatabase][I-RDB034005] Firebase Database connection was forcefully killed by the server.  Will not attempt reconnect. Reason: Invalid appcheck token.
    

如要重新啟用 App Check,請按照下列步驟操作:

  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」一文,瞭解如何使用遠端設定,逐步為使用者推出 App Check

以下是可能對您有幫助的其他資源

本程式碼研究室所述的設定適用於大多數情況,但 App Check 可讓您視需求彈性調整,詳情請點選下列連結: