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 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 を使用している場合は、次のように Factory を設定します。

      Swift

      AppCheck.setAppCheckProviderFactory(DeviceCheckProviderFactory())

      Objective-C

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

ステップ 3: トークン プロバイダを追加する

アプリのルートレベルに AppCheckTokenProvider という名前のファイル(Objective-C を使用している場合は AppCheckTokenProvider.hAppCheckTokenProvider.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 を初期化する

GMSServices を使用して 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
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: デバッグを有効にする(省略可)

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 トークンがないすべてのトラフィックを拒否します。