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

1.はじめに

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

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

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

構築するもの

このコードラボでは、既存のサンプルアプリケーションにアプリチェックを追加して適用し、プロジェクトのリアルタイムデータベースが不正なアプリやデバイスからアクセスされないように保護します。

あなたが学ぶこと

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

必要なもの

  • Xcode13.3.1以降
  • 新しいアプリ識別子を作成できるAppleDeveloperアカウント
  • AppAttestをサポートするiOS/iPadOSデバイス(App Attest APIの可用性について学ぶ)

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

iOSリポジトリ用のFirebaseQuickstartsには、さまざまなFirebase製品をデモンストレーションするためのサンプルアプリが含まれています。このコードラボのベースとして、SwiftUI用のFirebaseデータベースクイックスタートアプリを使用します。

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

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

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

cd database/DatabaseExampleSwiftUI/DatabaseExample
xed .

3.アプリにアプリチェックを追加します

  1. SwiftPackageManagerがプロジェクトの依存関係を解決するのを待ちます。
  2. DatabaseExample (iOS)アプリターゲットの[全般]タブを開きます。次に、[フレームワーク、ライブラリ、埋め込みコンテンツ]セクションで、[ + ]ボタンをクリックします。
  3. FirebaseAppCheckを追加する場合に選択します。

4.AppCheckプロバイダーファクトリを作成してインストールします

  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クラスのインスタンスをAppCheckプロバイダーファクトリとして設定します。
    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プロジェクトでアプリチェックを使用するには、Firebaseコンソールで次の手順を実行する必要があります。

  • Firebaseプロジェクトを設定します。
  • iOSアプリをFirebaseプロジェクトに追加します。
  • Firebase認証を構成します。
  • 保護するRealtimeDatabaseインスタンスを初期化します。
  • アプリチェックを構成します。

プロジェクトを作成する

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

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

リアルタイムデータベースインスタンスを作成する

次に、Firebaseコンソールの[リアルタイムデータベース]セクションに移動します。

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

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

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

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

iOSアプリを接続します

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

  1. 新しいプロジェクトの[プロジェクトの概要]画面で、[ +アプリを追加]ボタンをクリックしてから、[ iOS + ]アイコンをクリックして、Firebaseプロジェクトに新しいiOSアプリを追加します。
  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認証を構成します。

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

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

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

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

アプリを試してみてください

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

6.AppAttestアテステーションプロバイダーを構成します

この手順では、FirebaseコンソールでAppAttestプロバイダーを使用するようにAppCheckを設定します。

  1. Firebaseコンソールで、コンソールの[アプリチェック]セクションに移動します。
  2. [開始]をクリックします。
  3. [アプリ]タブで、アプリをクリックして詳細を展開します。
  4. [ AppAttest]をクリックしてAppAttestを構成し、Apple DeveloperアカウントのチームIDを入力します(これは、Apple Developerポータルの[メンバーシップ]セクションにあります)。 1645f7a369b678c2.png
  5. [保存]をクリックします。

これにより、新しいアプリに接続されたFirebaseプロジェクトが機能し、アプリチェックが有効になります。

これで、特定の認証サービスを構成する準備が整いました。このワークフローの詳細については、iOSでAppAttestを使用してアプリチェックを有効にするを参照してください。

7.アプリケーションのAppAttestを構成します

次に、Firebase App Check SDKを入手して、クライアントコードを実装します。

まず、SDKがAppleのApp Attest APIを使用して、アプリから送信されるリクエストがアプリの正当なインスタンスから送信されるように、Xcodeプロジェクトを構成する必要があります。

  1. XcodeプロジェクトにアプリターゲットのAppAttest機能を追加します。
  2. アプリのターゲット設定で[署名と機能]タブを開きます
  3. + 」ボタンをクリックします
  4. ダイアログで、 AppAttest機能を見つけて選択しますae84cd988a5fab31.png
  5. 前の手順を実行すると、ファイルDatabaseExample (iOS).entitlementsがXcodeプロジェクトのルートフォルダーに表示されます。
  6. DatabaseExample (iOS).entitlementsファイルで、AppAttestEnvironmentキーの値を本番App Attest Environmentに変更しますproduction.

これらの手順を完了し、物理iOSデバイス(iPhone / iPad)でアプリを起動した後も、アプリはリアルタイムデータベースにアクセスできます。後のステップで、不正なアプリやデバイスから送信されるリクエストをブロックするアプリチェックを適用します。

このワークフローの詳細については、iOSでAppAttestを使用してアプリチェックを有効にするを参照してください。

8.iOSシミュレーターのデバッグアテステーションプロバイダーを構成します

Firebase App Check Debugプロバイダーを使用すると、開発プロセス中に、iOSシミュレーターなど、信頼できない環境でFirebaseAppCheckを適用してアプリケーションをテストできます。次に、デバッグプロバイダーを一緒に構成する必要があります。

アプリに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
  }
}

このアプローチにより、環境に応じてAppCheckをより柔軟に構成できます。たとえば、 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()
}

これにより、独自のAppCheckプロバイダーファクトリを作成するためのコードを数行節約できます。

Firebaseコンソールにデバッグシークレットを登録します

iOSシミュレーターからデバッグシークレットを取得する

  1. AppCheckDebugProviderFactory (上記のオプション2)をインストールすることを選択した場合は、アプリの起動引数に-FIRDebugEnabledを追加して、アプリのデバッグログを有効にする必要があります。 f1c6b477a373e144.png
  2. シミュレーターでアプリを実行する
  3. Xcodeコンソールでデバッグシークレットを見つけます。コンソールフィルターを使用すると、次のようにすばやく見つけることができます。 d4c65af93e369c55.png

注:デバッグシークレットは、アプリの最初の起動時にシミュレーター用に生成され、ユーザーのデフォルトに保存されます。アプリを削除するか、シミュレーターをリセットするか、別のシミュレーターを使用すると、新しいデバッグシークレットが生成されます。必ず新しいデバッグシークレットを登録してください。

デバッグシークレットを登録する

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

これらの手順を実行すると、アプリチェックが適用されている場合でもシミュレーターでアプリを使用できます。

注:デバッグプロバイダーは、デバッグシークレットリークの防止に役立つように特別に設計されています。現在のアプローチでは、デバッグシークレットをソースコードに保存する必要はありません。

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

9. FirebaseRealtimeDatabaseのアプリチェックの実施を有効にする

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

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

  1. [アプリチェック]セクションのFirebaseコンソールで、[リアルタイムデータベース]をクリックして詳細を展開します。
  2. [強制]をクリックします。

64e6a81fa979b635.png

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

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

不正なアプリでリアルタイムデータベースにアクセスしてみてください

App Checkの実施が実際に行われていることを確認するには、次の手順に従います。

  1. DatabaseExampleAppのアプリエントリポイントのinitメソッドでAppCheck登録コードをコメントアウトして、AppCheck登録をオフにします。
  2. [デバイス]>[すべてのコンテンツと設定を消去]を選択して、シミュレーターをリセットします。これにより、シミュレータがワイプされます(そしてデバイストークンが無効になります)。
  3. シミュレーターでアプリを再度実行します。
  4. 次のエラーメッセージが表示されます
    [FirebaseDatabase][I-RDB034005] Firebase Database connection was forcefully killed by the server.  Will not attempt reconnect. Reason: Invalid appcheck token.
    

アプリチェックを再度有効にするには、次の手順を実行します。

  1. DatabaseExampleAppのAppCheck登録コードのコメントを解除します。
  2. アプリを再起動します。
  3. Xcodeのコンソールにある新しいAppCheckトークンに注意してください。
  4. Firebaseコンソールのアプリのアプリチェック設定にデバッグトークンを登録します。
  5. アプリを再実行します。
  6. エラーメッセージが表示されなくなり、アプリに新しい投稿やコメントを追加できるようになります。

10.おめでとうございます!

9785d32f18b995d2.gif

今、あなたは方法を知っています:

  • 既存のプロジェクトにアプリチェックを追加する
  • アプリの製品版用にAppAttestアテステーションプロバイダーを構成します
  • シミュレーターでアプリをテストするようにデバッグ認証プロバイダーを構成します
  • アプリのバージョンロールアウトを確認して、Firebaseプロジェクトにアプリチェックを適用するタイミングを確認してください
  • アプリチェックの実施を有効にする

次のステップ

Remote Configを使用して、 FirebaseRemoteConfigコードラボを使用してFirebaseAppCheckを段階的に展開するユーザーにAppCheckを段階的に展開する方法を学びます

これらはあなたが役立つと思うかもしれない他のリソースです

このコードラボで説明されているセットアップはほとんどの場合に機能しますが、App Checkを使用すると、必要に応じて柔軟性を高めることができます。詳細については、次のリンクを確認してください。