使用 Firebase Remote Config 逐步推出 Firebase App Check

一、簡介

您可以將Firebase App Check與 App Attest 結合使用來保護您的後端服務並驗證對 Firebase 服務的請求是否來自您的真實應用。

通常建議用戶逐步加入應用程式證明服務,以避免達到配額限制。有關更多信息,請參閱 Apple 的“準備使用應用程式證明服務”文件。

使用 Apple 的 App Store Connect 功能增量發布應用程式更新的能力(如「分階段發布版本更新」所述)可以讓 App Check 的推出更加順利。這是一個直接、簡單的解決方案。但是,分階段發布應用程式版本更新不允許您在不發布新應用程式版本的情況下控制現有更新應用程式的推出或變更行為。

對 App Check with App Attest 推出進行更多控制的一種方法是使用 Firebase Remote Config 一次為一定比例的應用程式使用者啟用 App Check with App Attest。這可能有助於避免來自證明伺服器的限制。 Google Analytics 可用於觀察此次推出對使用者的影響。

你將學到什麼

在此多步驟 Codelab 中,您將了解如何使用 Firebase Remote Config 為您的應用程式推出 App Check。

此 Codelab 使用基於 DatabaseExample 快速入門應用並與 Firebase App Check 整合的 Firebase 項目,如適用於 Apple 平台的 Firebase App Check 程式碼實驗室中所述。 DatabaseExample 快速入門應用程式可讓使用者使用 Firebase 即時資料庫的功能登入並新增貼文。

您也可以調整此 Codelab 中的步驟來測試您自己的應用。

先決條件

你需要什麼

  • Xcode 12.5+
  • 對於應用程式證明測試:
    • 允許您建立新應用程式識別碼的 Apple 開發者帳戶
    • 具有明確 App ID 且啟用了 App Attest 功能的應用程式。如果您需要有關該過程的協助,請參閱註冊應用程式 ID啟用應用程式功能文章。
    • 支援App Attest的iOS/iPadOS設備
  • Firebase 專案包含:
  • 存取您應用的關聯 Firebase 項目,並有權建立和管理遠端配置以及查看 Google Analytics(分析)

2. 建立自訂證明提供者

在此步驟中,我們將建立一個自訂提供者類,以便僅在啟用應用程式證明時提供令牌。遠端設定依賴已配置的 Firebase 應用程式實例,您在此步驟中實作的自訂提供者可充當佔位符來完成設定。

要完成以下步驟,您需要在 Xcode 中套用的框架、程式庫和嵌入式內容部分中新增FirebaseFirebaseRemoteConfigFirebaseAnalytics 。有關如何執行此操作的範例,請參閱適用於 Apple 平台的 Firebase 應用程式檢查 Codelab

  1. 建立一個檔案“ MyAppCheckProvider ”,它是符合AppCheckProvider協定的NSObject的子類別。
  2. 包含一個空的getToken()方法,您稍後將填寫該方法。

請參閱以下具有空getToken()方法的自訂提供者類別的範例程式碼。

// MyAppCheckProvider.swift

import Firebase
import FirebaseAnalytics
import FirebaseAppCheck
import FirebaseRemoteConfig

class MyAppCheckProvider: NSObject, AppCheckProvider {
  func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) {}
}

要實例化AppAttestProvider ,您需要傳遞對應FirebaseApp的實例。為其建立一個儲存屬性並接受它作為初始化參數:

// MyAppCheckProvider.swift

import Firebase
import FirebaseAnalytics
import FirebaseAppCheck
import FirebaseRemoteConfig

class MyAppCheckProvider: NSObject, AppCheckProvider {
  // Firebase app instance served by the provider.
  let firebaseApp: FirebaseApp

  // The App Check provider factory should pass the FirebaseApp instance.
  init(app: FirebaseApp) {
    self.firebaseApp = app
    super.init()
  }

  func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) {}
}

將令牌請求轉發給應用程式證明提供商

現在,您已擁有將令牌請求轉發到getToken()方法中的應用程式證明提供者的一切。

注意:在FirebaseAppCheck 框架參考中了解更多關於getToken()方法的資訊。

將以下程式碼加入您的getToken()方法:

// MyAppCheckProvider.swift

import Firebase
import FirebaseAnalytics
import FirebaseAppCheck
import FirebaseRemoteConfig

class MyAppCheckProvider: NSObject, AppCheckProvider {
  // Firebase app instance served by the provider.
  let firebaseApp: FirebaseApp

  // The App Check provider factory should pass the FirebaseApp instance.
  init(app: FirebaseApp) {
    self.firebaseApp = app
    super.init()
  }

  private lazy var appAttestProvider = AppAttestProvider(app: firebaseApp)

  func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) {
    // Fetch App Attest flag from Remote Config
    let remoteConfig = RemoteConfig.remoteConfig(app: firebaseApp)
    remoteConfig.fetchAndActivate { remoteConfigStatus, error in
      // Get App Attest flag value
      let appAttestEnabled = remoteConfig.configValue(forKey: "AppAttestEnabled").boolValue

      guard appAttestEnabled else {
        // Skip attestation if App Attest is disabled. Another attestation
        // method like DeviceCheck may be used instead of just skipping.
        handler(nil, MyProviderError.appAttestIsDisabled)
        return
      }

      // Try to obtain an App Attest provider instance and fail if cannot
      guard let appAttestProvider = self.appAttestProvider else {
        handler(nil, MyProviderError.appAttestIsUnavailable)
        return
      }

      // If App Attest is enabled for the app instance, then forward the
      // Firebase App Check token request to the App Attest provider
      appAttestProvider.getToken(completion: handler)
    }
  }
}

enum MyProviderError: Error {
  case appAttestIsDisabled
  case appAttestIsUnavailable
  case unexpected(code: Int)
}

前面的程式碼檢查遠端配置AppAttestEnabled布林參數(此遠端配置參數將在稍後的 Codelab 中建立)。如果值為 false,則程式碼失敗,表示目前裝置上尚未推出 App Check。如果值為 true,則程式碼會嘗試取得 App Attest 提供程序,如果無法取得則會失敗。如果這些錯誤檢查通過,程式碼會將令牌請求轉發給 App Attest 提供者。

新增分析事件

透過新增分析事件,您可以更了解應用程式檢查部署的成功程度。分析將有助於確定是否應該為更多受眾啟用應用程式證明。

記錄兩個 Analytics 事件:成功時記錄AppAttestSuccess ,失敗時記錄AppAttestFailure 。這兩個 Analytics 事件可以幫助追蹤 App Check 部署的成功情況,並幫助您決定是否應該繼續進行更大規模的部署。

func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) {
  // Fetch Remote Config.
  let remoteConfig = RemoteConfig.remoteConfig(app: firebaseApp)
  remoteConfig.fetchAndActivate { remoteConfigStatus, error in
    // Get App Attest flag value from Remote Config.
    let appAttestEnabled = remoteConfig.configValue(forKey: "AppAttestEnabled").boolValue

    guard appAttestEnabled else {
      // Skip attestation if App Attest is disabled. Another attestation
      // method like DeviceCheck may be used instead of just skipping.
      handler(nil, MyProviderError.appAttestIsDisabled)
      return
    }

    // Try to obtain an App Attest provider instance and fail otherwise.
    guard let appAttestProvider = self.appAttestProvider else {
      handler(nil, MyProviderError.appAttestIsUnavailable)
      return
    }

    // If App Attest is enabled for the app instance, then forward the
    // Firebase App Check token request to the App Attest provider.
    appAttestProvider.getToken { token, error in
      // Log an Analytics event to track attestation success rate.
      let appAttestEvent: String
      if (token != nil && error == nil) {
        appAttestEvent = "AppAttestSuccess"
      } else {
        appAttestEvent = "AppAttestFailure"
      }
      Analytics.logEvent(appAttestEvent, parameters: nil)

      // Pass the result to the handler
      handler(token, error)
    }
  }
}

3.更新ProviderFactory類

實作將令牌請求轉送到 App Attest 提供者的邏輯並新增一些 Analytics 事件後,您需要更新在App Check for Apple Platforms Codelab中建立的MyAppCheckProviderFactory.class 。此類別將以模擬器的App Check 偵錯提供者為目標,否則以您的自訂提供者為目標。

在您在適用於 Apple 平台的 Firebase App Check Codelab中建立的MyAppCheckProviderFactory類別中編輯以下程式碼:

// 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
      if #available(iOS 14.0, *) {
        // Use your custom App Attest provider on real devices.
        return MyAppCheckProvider(app: app)
      } else {
        return DeviceCheckProvider(app: app)
      }
      #endif
  }
}

在配置FirebaseApp之前確認您已設定AppCheckProviderFactory

// DatabaseExampleApp.swift

import SwiftUI
import Firebase
import FirebaseAppCheck

@main
struct DatabaseExampleApp: App {
  init() {
    AppCheck.setAppCheckProviderFactory(MyAppCheckProviderFactory())
    FirebaseApp.configure()
  }

  // ...
}

4. 在 Firebase 控制台中新增遠端設定參數

現在您將遠端設定參數AppAttestEnabled新增至 Firebase 控制台。您的getToken方法需要此參數。

若要在 Firebase 控制台中建立遠端設定參數:

  1. 打開您的專案的遠端配置並點擊新增參數。如果這是您第一次使用遠端配置,請按一下建立配置
  2. 參數名稱(鍵)欄位中,輸入AppAttestEnabled
  3. 資料類型下拉清單中,選擇布林值
  4. 預設值下拉清單中,選擇false

在 Firebase 控制台中建立遠端設定參數

在按一下「儲存」之前,為 10% 的使用者建立條件值:

  1. 點選新增>條件值>建立新條件
  2. 名稱欄位中,輸入條件名稱。
  3. “套用如果...”下,選擇“隨機百分位數中的使用者”“<= ”,然後在“ %”欄位中輸入10
  4. 點選建立條件

在 Firebase 控制台中定義遠端設定條件

將條件值設為true ,以便應用程式證明將推廣到 10% 的用戶。

  1. 將剛剛建立的條件的值設為true
  2. 按一下「儲存」

在 Firebase 控制台中查看遠端設定參數

完成後,發布遠端配置變更。

在您的裝置上測試部署

若要在不修改應用程式碼的情況下測試裝置上的不同遠端設定標誌值,請依照使用 A/B 測試建立 Firebase 遠端設定實驗教學課程,AppAttestEnabled參數上設定實驗。教程部分「在測試設備上驗證您的實驗」解釋如何為您的測試設備分配不同的值。

最後一步是使用 Google Analytics 來監控應用程式證明部署是否成功。

5. 檢查 AppCheck 部署是否成功

您可以在 Analytics Events 儀表板上衡量部署是否成功。監控AppAttestSuccessAppAttestFailure事件。最多可能需要 24 小時才能在儀表板中查看事件。或者,您可以啟用偵錯並使用 DebugView 更快地查看偵錯事件。

或者,您可以監控 Crashlytics 儀表板以了解崩潰率的增加。有關將 Crashlytics 添加到您的應用程式的更多信息,請參閱Firebase Crashlytics 入門

一旦您看到大部分AppAttestSuccess事件和少量AppAttestFailure事件,這是一個好兆頭,表示您可以透過修改遠端設定參數AppAttestEnabled中的條件來增加啟用 App Attest 的使用者百分比。

在 Firebase 控制台中查看 Analytics 事件

可選:利用 Google Analytics 受眾

如果您想進一步利用AppAttestEnabled Analytics 事件,您可以建立Analytics Audience來追蹤將AppAttestEnabled設定為 true 的使用者。

App Attest 隨 iOS 14.0 一起發布。您的某些用戶可能未使用此版本,因此沒有資格進行應用程式證明。您可以記錄另一個 Analytics 事件來追蹤這些用戶,然後針對該受眾群體使用另一種證明方法,例如DeviceCheck

可選:使用 Crashlytics 監控崩潰

為了更了解應用程式在推出期間的穩定性,請使用Firebase Crashlytics來監控崩潰和非致命事件。

6. 恭喜!

您已成功推出遠端設定的 App Check 🎉

其他資源: