使用 App Check 保護 iOS 版 Navigation SDK

Firebase App Check 會封鎖來自正當應用程式以外來源的流量,保護應用程式對 Google 地圖平台發出的呼叫。方法是向 App Attest 等驗證供應商要求評估應用程式或裝置的真實性。將應用程式與 App Check 整合後,即可防範惡意和未經授權的要求,進而避免帳單出現未經授權的費用。此外,App Check 也大幅提升車隊應用程式生態系統的即時中斷回報功能,因此所有使用您應用程式的駕駛人都能受益。詳情請參閱「中斷回報」。

為什麼要使用 App Check?

App Check 可保護 iOS 版 Navigation SDK 的兩個不同區域:主要導航功能和中斷回報。

App Check 可協助封鎖來自惡意或未經授權來源的主要 Navigation SDK for iOS 要求。這項功能可保護專案免於帳單詐欺和配額用盡,直接為您帶來好處。

回報中斷

如果應用程式支援即時回報中斷情形和投票功能,強烈建議使用 App Check。啟用 App Check 功能後,系統會根據所有即時回饋,為駕駛人提供最準確的路線。

為什麼 App Check 對於回報至關重要:

  • 高信任度的封路資訊:影響路線的事件 (例如封路) 可能會大幅改變所有駕駛人的路線規劃行為。為避免地圖遭到破壞、出現垃圾內容或不實回報,Google 道路封閉中斷的審核基礎架構會依據強大的裝置和應用程式完整性信號運作。
  • App Check 如何驗證回報:從 Navigation SDK for iOS 傳送的使用者回報和投票會包含 App Check 權杖,Google 後端會使用該權杖驗證意見回饋的合法性,提高信任等級,並評估意見回饋對線上地圖的影響。
  • 省略 App Check 的影響:如果提交的報表沒有有效的 App Check 權杖,系統會以信任度較低的模式評估,且可能只會將其視為無聲信號處理。也就是說,使用者仍可回報和投票,但他們的回報內容較不可能顯示在地圖上或影響其他駕駛人的路線,且需要額外驗證。

我是否適合使用 App Check?

在大多數情況下,建議使用 App Check,但在下列情況下,不需要或不支援 App Check:

  • 私人或實驗性應用程式:如果應用程式未公開發布,就不需要使用 App Check。
  • 遭駭裝置:建議使用的驗證供應商可防止 iOS 版 Navigation SDK 在不可信任的裝置上執行,例如已啟用 Root 權限或已越獄解鎖的手機。如要支援這些裝置,請部署自訂驗證供應商

導入步驟總覽

整體來說,如要整合應用程式與 App Check,請按照下列步驟操作:

  1. 將 Firebase 新增至應用程式。
  2. 加入 App Check 程式庫並初始化 App Check。
  3. 新增權杖提供者。這個步驟會叫用您選擇的認證供應商,驗證裝置或應用程式的完整性。
  4. 初始化 Navigation 和 App Check API。
  5. 啟用偵錯功能。這在開發或持續整合 (CI) 環境中非常實用。
  6. 啟用強制執行前,請先監控應用程式請求。這樣一來,您就能順利強制執行 App Check,不會對使用者造成干擾。

規劃整合 App Check 時的注意事項

  • 驗證提供者配額:我們建議的驗證提供者 (DeviceCheck 或 App Attest) 須遵守 Apple 設定的配額和限制
  • 啟動延遲:在大多數情況下,使用者正常使用時不會遇到延遲問題,因為 App Check 權杖會快取在裝置上。系統會在背景自動更新 App Check 權杖,避免權杖過期,確保效能不受影響。不過,如果沒有有效的 App Check 權杖,應用程式使用者在啟動時會遇到一些延遲。舉例來說,如果快取權杖過期或遺失,冷啟動期間就會發生這種延遲。
  • 權杖存留時間:存留時間 (TTL) 會決定 App Check 權杖的效期,權杖過期前必須重新整理。您可以在 Firebase 控制台中,將這段時間設為 30 分鐘到 7 天。建議將時長設為 1 小時,做為安全基準,但 SDK 會自動嘗試在 TTL 時長的一半左右進行背景重新整理。如需逐步操作說明,請參閱 Firebase App Check 說明文件

將應用程式與 App Check 整合

必要條件和規定

  • 已安裝 Navigation SDK for iOS 11.0 以上版本的應用程式。
  • 應用程式的軟體包 ID
  • Apple Developer Console「Membership」(成員) 分頁中的團隊 ID。
  • 如果您打算使用 DeviceCheck,請準備私密金鑰檔案金鑰 ID
  • 您必須是 Google Cloud 控制台中應用程式的擁有者。
  • Google Cloud 控制台中的應用程式專案 ID。

步驟 1:將 Firebase 新增至應用程式

按照 Firebase 開發人員說明文件中的操作說明,將 Firebase 新增至應用程式。將 GoogleService-Info.plist 檔案 (未經修改) 新增至專案的根層級。

AppDelegate 檔案中,匯入下列模組:

Swift

import FirebaseCore
import FirebaseAppCheck
import GoogleNavigation

Objective-C

@import FirebaseCore;
@import FirebaseAppCheck;
@import GoogleNavigation;

步驟 2:新增 App Check 程式庫並初始化 App Check

Firebase 會提供各個預設認證供應商的操作說明。這些操作說明會引導您設定 Firebase 專案,並將 App Check 程式庫新增至應用程式。請按照提供的程式碼範例初始化 App Check。

  1. 按照 Firebase 操作說明新增 App Check 程式庫:
  2. AppDelegate 中初始化 App Check:
    • 如果您使用 App Attest,請建立 AppCheckProviderFactory 的實作項目,並在呼叫 FirebaseApp.configure() 前註冊:

      Swift

      class YourAppCheckProviderFactory: NSObject, AppCheckProviderFactory {
          func createProvider(with app: FirebaseApp) -> AppCheckProvider? {
              return AppAttestProvider(app: app)
          }
      }
      // In application(_:didFinishLaunchingWithOptions:)
      let providerFactory = YourAppCheckProviderFactory()
      AppCheck.setAppCheckProviderFactory(providerFactory)
      FirebaseApp.configure()

      Objective-C

      #import <FirebaseCore/FirebaseCore.h>
      #import <FirebaseAppCheck/FirebaseAppCheck.h>
      
      @interface YourAppCheckProviderFactory : NSObject <FIRAppCheckProviderFactory>
      @end
      
      @implementation YourAppCheckProviderFactory
      - (nullable id<FIRAppCheckProvider>)createProviderWithApp:(FIRApp *)app {
          return [[FIRAppAttestProvider alloc] initWithApp:app];
      }
      @end
      
      // In application:didFinishLaunchingWithOptions:
      YourAppCheckProviderFactory *providerFactory = [[YourAppCheckProviderFactory alloc] init];
      [FIRAppCheck setAppCheckProviderFactory:providerFactory];
      [FIRApp configure];
    • 如果您改用 DeviceCheck,請使用下列項目設定工廠:

      Swift

      AppCheck.setAppCheckProviderFactory(DeviceCheckProviderFactory())

      Objective-C

      FIRDeviceCheckProviderFactory *providerFactory = [[FIRDeviceCheckProviderFactory alloc] init];
      [FIRAppCheck setAppCheckProviderFactory:providerFactory];

步驟 3:新增權杖供應商

在應用程式的根層級建立名為 AppCheckTokenProvider 的檔案 (如果您使用 Objective-C,則建立名為 AppCheckTokenProvider.hAppCheckTokenProvider.m 的兩個檔案)。

這個類別必須符合 GMSAppCheckTokenProvider 通訊協定,並實作 fetchAppCheckTokenWithCompletion 方法。

Swift

import Foundation
import FirebaseAppCheck
import GoogleNavigation

class AppCheckTokenProvider: NSObject, GMSAppCheckTokenProvider {
    func fetchAppCheckToken(completion: @escaping (String?, Error?) -> Void) {
        AppCheck.appCheck().token(forcingRefresh: false) { token, error in
            if let error = error {
                print("App Check Error: \(error)")
                completion(nil, error)
                return
            }
            guard let token = token else {
                completion(nil, NSError(domain: "AppCheck", code: -1, userInfo: [NSLocalizedDescriptionKey: "Token is nil"]))
                return
            }
            print("App Check Token: \(token.token)")
            completion(token.token, nil)
        }
    }
}

Objective-C

// AppCheckTokenProvider.h
#import <Foundation/Foundation.h>
#import <GoogleNavigation/GoogleNavigation.h>

NS_ASSUME_NONNULL_BEGIN

@interface AppCheckTokenProvider : NSObject <GMSAppCheckTokenProvider>
@end

NS_ASSUME_NONNULL_END
// AppCheckTokenProvider.m
#import "AppCheckTokenProvider.h"
#import <FirebaseAppCheck/FirebaseAppCheck.h>

@implementation AppCheckTokenProvider
- (void)fetchAppCheckTokenWithCompletion:(void (^)(NSString * _Nullable token, NSError * _Nullable error))completion {
    [[FIRAppCheck appCheck] tokenForcingRefresh:NO
                                     completion:^(FIRAppCheckToken * _Nullable token, NSError * _Nullable error) {
        if (token) {
            completion(token.token, nil);
        } else {
            completion(nil, error);
        }
    }];
}
@end

步驟 4:初始化 Navigation 和 App Check API

初始化 Navigation SDK for iOS (使用 GMSServices),並將共用不透明服務控制代碼轉換為 GMSServices,藉此註冊權杖供應商例項:

Swift

// In application(_:didFinishLaunchingWithOptions:)
GMSServices.provideAPIKey("YOUR_API_KEY")

// Register your App Check token provider before initializing Navigation SDK for iOS
if let services = GMSServices.sharedServices() as? GMSServices {
    services.appCheckTokenProvider = AppCheckTokenProvider()
}

Objective-C

// In application:didFinishLaunchingWithOptions:
[GMSServices provideAPIKey:@"YOUR_API_KEY"];

// Register your App Check token provider before initializing Navigation SDK for iOS
((GMSServices *)[GMSServices sharedServices]).appCheckTokenProvider = [[AppCheckTokenProvider alloc] init];

步驟 5:啟用偵錯功能 (選用)

對 iOS 版 Navigation SDK 啟用 App Check 後,應用程式中依賴 iOS 版 Navigation SDK 的功能將無法在模擬器或持續整合 (CI) 環境中執行,因為這些環境不符合有效裝置的資格。如要在開發和測試期間於這些環境中執行應用程式,您必須建立應用程式的偵錯版本,並使用 App Check 偵錯提供者,而非正式版認證提供者。

  1. AppDelegate 中設定偵錯服務工廠:

    Swift

    #if targetEnvironment(simulator)
    let providerFactory = AppCheckDebugProviderFactory()
    #else
    let providerFactory = YourAppCheckProviderFactory()
    #endif
    AppCheck.setAppCheckProviderFactory(providerFactory)

    Objective-C

    #if TARGET_OS_SIMULATOR
    id<FIRAppCheckProviderFactory> providerFactory = [[FIRAppCheckDebugProviderFactory alloc] init];
    #else
    id<FIRAppCheckProviderFactory> providerFactory = [[YourAppCheckProviderFactory alloc] init];
    #endif
    [FIRAppCheck setAppCheckProviderFactory:providerFactory];
  2. 在 Xcode 專案中啟用記錄功能、啟動應用程式,並在控制台記錄中找出本機偵錯權杖。
  3. 複製這個偵錯權杖,並新增至 Firebase 控制台。詳情請參閱 Firebase App Check 偵錯供應商說明文件

步驟 6:監控應用程式要求並決定強制執行方式

啟用強制執行前,請先監控應用程式要求,確保不會中斷正當使用者的作業。

  1. 前往 Firebase 控制台的 App Check 指標畫面,查看已驗證和未驗證流量的百分比。
  2. 確認大部分流量都經過驗證,且正當使用者已更新至含有 App Check 導入作業的應用程式版本後,即可啟用強制執行功能。
  3. 強制執行後,App Check 會拒絕所有不具備有效 App Check 權杖的流量。