AppleプラットフォームのFirebaseアプリチェック

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

1.はじめに

Firebase App Check は、リクエストが正当なアプリやデバイスからのものであることを確認することで、不正請求やフィッシングなどの悪用からバックエンド リソースを保護するのに役立ちます。 Firebase サービスと独自のバックエンド サービスの両方と連携して、リソースを安全に保ちます。

Firebase App Checkの詳細については、Firebase のドキュメントをご覧ください。

App Check は、プラットフォーム固有のサービスを使用して、アプリやデバイスの整合性を検証します。これらのサービスは、認証プロバイダーと呼ばれます。そのようなプロバイダーの 1 つが Apple のApp Attestサービスで、App Check はこれを使用して Apple のアプリとデバイスの信頼性を検証できます。

構築するもの

この Codelab では、既存のサンプル アプリケーションに App Check を追加して適用し、プロジェクトの Realtime Database が不正なアプリやデバイスからアクセスされないように保護します。

学習内容

  • Firebase App Check を既存のアプリに追加する方法。
  • さまざまな Firebase App Check 構成証明プロバイダーをインストールする方法。
  • アプリの App Attest を構成する方法。
  • アプリの開発中にシミュレーターでアプリをテストするようにデバッグ構成証明プロバイダーを構成する方法。

必要なもの

  • Xcode 13.3.1 以降
  • 新しいアプリ識別子を作成できる Apple Developer アカウント
  • App Attest をサポートする iOS/iPadOS デバイス (App Attest API の可用性についてはこちらをご覧ください)

2. スターター プロジェクトを取得する

Firebase Quickstarts for iOS リポジトリには、さまざまな Firebase プロダクトを紹介するためのサンプル アプリが含まれています。この Codelab のベースとして、SwiftUI 用の Firebase データベース クイックスタート アプリを使用します。

コマンドラインからFirebase Quickstarts for iOS リポジトリのクローンを作成します。

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

Xcode で Realtime Database SwiftUI クイックスタート アプリ プロジェクトを開きます。

cd database/DatabaseExampleSwiftUI/DatabaseExample
xed .

3. App Check をアプリに追加する

  1. Swift Package Manager がプロジェクトの依存関係を解決するまで待ちます。
  2. DatabaseExample (iOS)アプリ ターゲットの [全般] タブを開きます。次に、[フレームワーク、ライブラリ、および埋め込みコンテンツ] セクションで、[ + ] ボタンをクリックします。
  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 プロジェクトをセットアップします。
  • iOS アプリを Firebase プロジェクトに追加します。
  • Firebase 認証を構成します。
  • 保護する Realtime Database インスタンスを初期化します。
  • アプリ チェックを構成します。

プロジェクトを作成する

まず、Firebase プロジェクトを作成する必要があります。

  1. Firebase コンソールで、[プロジェクトの追加] を選択します。
  2. プロジェクトにApp Check Codelab名前を付けます
  3. [続行] をクリックします。
  4. このプロジェクトの Google アナリティクスを無効にしてから、[プロジェクトの作成] をクリックします。

Realtime Database インスタンスを作成する

次に、Firebase コンソールのRealtime Databaseセクションに移動します。

  1. [データベースの作成] ボタンをクリックして、データベース作成ワークフローを開始します。
  2. データベースのデフォルトの場所 ( us-central1 ) はそのままにして、 [次へ] をクリックします。
  3. [ロック モード] が選択されていることを確認し、[有効にする] ボタンをクリックして、データベースのセキュリティ ルールを有効にします。
  4. Realtime Database ブラウザの [ルール] タブに移動し、デフォルトのルールを次のように置き換えます:
    {
        "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. [公開] ボタンをクリックして、更新されたセキュリティ ルールを有効にします。

Firebase に接続する iOS アプリを準備する

サンプル アプリを物理デバイスで実行できるようにするには、必要なプロビジョニング プロファイルを Xcode が管理できるように、プロジェクトを開発チームに追加する必要があります。次の手順に従って、サンプル アプリを開発者アカウントに追加します。

  1. Xcode では、プロジェクト ナビゲーターでDatabaseExampleプロジェクトを選択します。
  2. DatabaseExample (iOS)ターゲットを選択し、 Signing & Capabilitiesタブを開きます。
  3. "Signing for DatabaseExample (iOS) requires a development team"というエラー メッセージが表示されます。
  4. バンドル識別子を一意の識別子に更新します。これを実現する最も簡単な方法は、 com.acme.samples.firebase.quickstart.DatabaseExampleなど、Web サイトの逆引きドメイン名を使用することです (この ID は使用しないでください。代わりに独自の一意の ID を選択してください)。
  5. 開発チームを選択します。
  6. Xcode が「Provisioning Profile: Xcode Managed Profile」とこのラベルの横に小さな情報アイコンを表示すると、すべてがうまくいったことがわかります。このアイコンをクリックすると、プロビジョニング プロファイルの詳細が表示されます。

iOS アプリを接続する

アプリの接続に関する詳細な説明については、iOS プロジェクトへの Firebase の追加に関するドキュメントをご覧ください。開始するには、Firebase コンソールで次の主な手順に従います。

  1. 新しいプロジェクトの [ Project Overview ] 画面で、[ + Add app ] ボタンをクリックし、次に [ iOS+ ] アイコンをクリックして、新しい iOS アプリを Firebase プロジェクトに追加します。
  2. アプリのバンドル ID を入力します ( com.acme.samples.firebase.quickstart.DatabaseExampleなど、前のセクションで定義したものを使用します。これは一意の識別子である必要があることに注意してください)。
  3. [アプリの登録]をクリックします。
  4. Firebase は、アプリに必要なすべての Firebase メタデータを含むGoogleService-Info.plistファイルを生成します。
  5. [ GoogleService-Info.plistをダウンロード] をクリックしてファイルをダウンロードします。
  6. Xcode では、プロジェクトに既にGoogleService-Info.plistという名前のファイルが含まれていることがわかります。最初にこのファイルを削除します。次のステップで、独自の Firebase プロジェクト用のファイルに置き換えます。
  7. 前の手順でダウンロードしたGoogleService-Info.plistファイルを Xcode プロジェクトのルート フォルダーにコピーし、それをDatabaseExample (iOS)ターゲットに追加します。名前がGoogleService-Info.plistであることを確認してください。
  8. 登録フローの残りのステップをクリックします。サンプル プロジェクトは既に正しく設定されているため、コードを変更する必要はありません。

Firebase 認証を構成する

ふぅ!これまでのところ、かなりの設定が必要ですが、しっかりと保持してください。 Firebase を初めて使用する場合は、すぐに慣れるワークフローの重要な部分を見てきました。

次に、このアプリの Firebase Authentication を構成します。

認証メール/パスワード サインイン プロバイダーを有効にする

  1. 引き続き Firebase コンソールで、コンソールの [認証]セクションを開きます。
  2. [開始する] をクリックして、プロジェクトの Firebase Authentication を設定します。
  3. [サインイン方法] タブを選択します。
  4. [ネイティブ プロバイダー]セクションで [メール/パスワード]を選択します。
  5. 電子メール/パスワードを有効にして、[保存] をクリックします。

テスト ユーザーを追加する

  1. [認証] セクションの [ユーザー] タブを開きます。
  2. [ユーザーを追加] をクリックします。
  3. テスト ユーザーのメール アドレスとパスワードを指定し、[ユーザーの追加] をクリックします。

アプリを試してみましょう

Xcode に戻り、iOS シミュレーターでアプリケーションを実行します。作成したテスト ユーザーのメール アドレスとパスワードを使用してサインインします。サインインしたら、投稿を作成し、既存の投稿にコメントを投稿し、投稿に星を付けたり外したりします。

6.App Attest 構成証明プロバイダーを構成する

このステップでは、Firebase コンソールで App Attest プロバイダを使用するように App Check を構成します。

  1. Firebase コンソールで、コンソールのApp Checkセクションに移動します。
  2. [開始する] をクリックします。
  3. [アプリ] タブで、アプリをクリックして詳細を展開します。
  4. [ App Attest] をクリックして App Attestを構成し、Apple 開発者アカウントのチーム ID を入力します (これは、Apple 開発者ポータルの [メンバーシップ] セクションにあります)。 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 & Capabilities ] タブを開きます
  3. 」ボタンをクリック
  4. ダイアログで、 App Attest機能を見つけて選択しますae84cd988a5fab31.png
  5. 前の手順を実行すると、ファイルDatabaseExample (iOS).entitlementsが Xcode プロジェクトのルート フォルダーに表示されます。
  6. DatabaseExample (iOS).entitlementsファイルで、 App Attest Environmentキーの値を production に変更しますproduction.

これらの手順を完了し、物理iOS デバイス (iPhone/iPad) でアプリを起動すると、アプリは引き続き Realtime Database にアクセスできます。後の手順で、App Check を実施します。これにより、不正なアプリやデバイスから送信されるリクエストがブロックされます。

このワークフローの詳細については、iOS で App Attest を使用して App Check を有効にする を参照してください。

8. iOS シミュレーターのデバッグ構成証明プロバイダーを構成する

Firebase App Check デバッグプロバイダを使用すると、開発プロセス中に、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をインストールする

より単純なケースでは、Firebase アプリケーション インスタンスを構成する前に、 AppCheckDebugProviderFactoryを一時的または条件付きでインストールできます。

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 ] セクションに移動します。
  2. [アプリ] タブで、アプリをクリックして詳細を展開します。
  3. オーバーフロー メニューで、 [デバッグ トークンの管理] を選択します。 d77c8ff768a00b4b.png
  4. Xcode コンソールからコピーしたシークレットを追加し、[保存] をクリックします。 f845c97b86f694d0.png

これらの手順の後、App Check が適用されていても、シミュレーターでアプリを使用できます。

注:デバッグ プロバイダーは、デバッグ シークレットの漏洩を防止するために特別に設計されました。現在のアプローチでは、デバッグ シークレットをソース コードに保存する必要はありません。

このフローの詳細については、ドキュメントを参照してください。 iOS のデバッグ プロバイダーで App Check を使用する を参照してください。

9. Firebase Realtime Database の App Check 適用を有効にする

今のところ、アプリは実際のデバイスのAppCheckProviderFactoryを返すAppAttestProviderを宣言しています。物理デバイスで実行する場合、アプリは構成証明を実行し、結果を Firebase バックエンドに送信します。ただし、Firebase バックエンドは引き続き、任意のデバイス、iOS シミュレーター、スクリプトなどからのリクエストを受け入れます。このモードは、App Check のない古いバージョンのアプリを使用しているユーザーがまだいて、アクセスを強制したくない場合に便利です。チェックはまだ。

ここで、App Check の適用を有効にして、Firebase アプリが正当なデバイスからのみアクセスできるようにする必要があります。 Firebase プロジェクトの適用を有効にすると、App Check が統合されていない古いバージョンのアプリは機能しなくなります。

  1. Firebase コンソールの [ App Check ] セクションで、[ Realtime Database ] をクリックして詳細を展開します。
  2. [強制]をクリックします。

64e6a81fa979b635.png

  1. 確認ダイアログの情報を読み、[強制] をクリックします。

これらの手順を完了すると、正当なアプリのみがデータベースにアクセスできるようになります。他のすべてのアプリはブロックされます。

違法なアプリで Realtime Database にアクセスしてみる

App Check の実施状況を確認するには、次の手順に従います。

  1. DatabaseExampleAppのアプリ エントリ ポイントのinitメソッドで App Check 登録コードをコメント アウトして、App Check 登録をオフにします。
  2. [Device] > [Erase All Content and Settings]を選択して、シミュレータをリセットします。これにより、シミュレーターがワイプされます (そして、デバイス トークンが無効になります)。
  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 Remote Config を使用して Firebase App Check を段階的にロールアウトする Codelabで、Remote Config を使用してユーザーに App Check を段階的にロールアウトする方法を学びます。

これらは、役立つと思われるその他のリソースです

この Codelab で説明されている設定はほとんどの場合に機能しますが、App Check は必要に応じてより柔軟に使用できます。詳細については、次のリンクを確認してください。