App Check を使用して Navigation SDK for iOS を保護する

Firebase App Check は、正規のアプリ以外のソースから送信されたトラフィックをブロックすることで、アプリから Google Maps Platform への呼び出しを保護します。これは、App Attest などの証明書プロバイダにアプリまたはデバイスの真正性の評価をリクエストすることで行われます。アプリを App Check と統合すると、悪意のある不正なリクエストに対する保護が追加され、不正な請求から課金を保護できます。また、App Check はフリートアプリ エコシステムにおけるリアルタイムの障害レポートを大幅に改善し、アプリを使用するすべてのドライバーにメリットをもたらします。詳しくは、障害レポートをご覧ください。

App Check を使用する理由

App Check は、Navigation SDK for iOS の 2 つの異なる領域(メインのナビゲーション機能と交通情報レポート)を保護します。

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 は必要ありません。
  • 不正使用されたデバイス: 推奨される証明書プロバイダは、root 権限取得または制限解除されているスマートフォンなど、信頼できないデバイスで Navigation SDK for iOS が実行されるのを防ぎます。これらのデバイスをサポートするには、カスタム構成証明プロバイダをデプロイします。

実装手順の概要

大まかには、次の手順でアプリを App Check と統合します。

  1. Firebase をアプリに追加します。
  2. App Check ライブラリを追加し、App Check を初期化します。
  3. トークン プロバイダを追加します。このステップでは、選択した証明書プロバイダを呼び出して、デバイスまたはアプリの完全性を検証します。
  4. Navigation API と App Check API を初期化します。
  5. デバッグを有効にします。これは、開発中や継続的インテグレーション(CI)環境で役立ちます。
  6. 適用を有効にする前に、アプリのリクエストをモニタリングします。これにより、ユーザーに影響を与えることなく App Check をシームレスに適用できます。

App Check の統合を計画する際の考慮事項

  • 証明書プロバイダの割り当て: 推奨される証明書プロバイダである DeviceCheck または App Attest には、Apple によって設定された割り当てと制限が適用されます。
  • 起動時のレイテンシ: ほとんどの場合、App Check トークンはデバイスにキャッシュされるため、通常の利用中にレイテンシが発生することはありません。システムは、シームレスなパフォーマンスを維持するために、有効期限が切れる前にバックグラウンドで App Check トークンを自動的に更新します。ただし、有効な App Check トークンが存在しない場合、アプリの起動時に遅延が発生します。たとえば、このレイテンシは、キャッシュに保存されたトークンが期限切れになっているか、存在しない場合のコールド スタート中に発生します。
  • トークンの TTL: 有効期間(TTL)は、App Check トークンが更新されるまでの有効期間を決定します。この期間は、Firebase コンソールで 30 分から 7 日の範囲で構成できます。安全なベースラインとして 1 時間の期間が推奨されますが、SDK は TTL 期間の約半分でバックグラウンド更新を自動的に試行します。コンソールでの手順については、Firebase App Check のドキュメントをご覧ください。

アプリを App Check と統合する

前提条件と要件

  • Navigation SDK for iOS バージョン 11.0 以降がインストールされているアプリ。
  • アプリのバンドル ID。
  • Apple Developer コンソールの [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.h と AppCheckTokenProvider.m という名前の 2 つのファイルを作成します)。

このクラスは、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 API と App Check API を初期化する

Navigation SDK for iOS を初期化し、GMSServices でトークン プロバイダ インスタンスを登録します。

Swift

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

// Register your App Check token provider before initializing Navigation SDK for iOS
GMSServices.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.appCheckTokenProvider = [[AppCheckTokenProvider alloc] init];

ステップ 5: デバッグを有効にする(省略可)

Navigation SDK for iOS で App Check が適用されると、Navigation SDK for iOS に依存するアプリの機能は、シミュレータまたは継続的インテグレーション(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 トークンがないすべてのトラフィックを拒否します。