Déploiement progressif de Firebase App Check à l'aide de Firebase Remote Config

1. Introduction

Vous pouvez utiliser Firebase App Check avec App Attest pour protéger vos services de backend et vérifier que les requêtes envoyées aux services Firebase proviennent bien de votre application authentique.

En règle générale, il est recommandé d'intégrer progressivement les utilisateurs au service App Attest pour éviter d'atteindre les limites de quota. Pour en savoir plus, consultez la documentation Apple Préparation à l'utilisation du service App Attest.

La possibilité de déployer les mises à jour d'application de manière incrémentielle à l'aide de la fonctionnalité App Store Connect d'Apple, comme décrit dans Déployer une mise à jour de version par étapes, peut faciliter le déploiement d'App Check. Il s'agit d'une solution simple et directe. Toutefois, la publication progressive d'une mise à jour de version d'application ne vous permet pas de contrôler le déploiement ni de modifier le comportement des applications existantes et mises à jour sans publier une nouvelle version de l'application.

Pour mieux contrôler le déploiement d'App Check avec App Attest, vous pouvez utiliser Firebase Remote Config afin d'activer App Check avec App Attest pour un pourcentage d'utilisateurs de votre application à la fois. Cela peut vous aider à éviter la limitation de débit des serveurs d'attestation. Vous pouvez utiliser Google Analytics pour observer l'impact du déploiement sur les utilisateurs.

Points abordés

Dans cet atelier de programmation en plusieurs étapes, vous allez apprendre à utiliser Firebase Remote Config pour déployer App Check dans votre application.

Cet atelier de programmation utilise un projet Firebase basé sur l'application de démarrage rapide DatabaseExample et intégré à Firebase App Check, comme décrit dans l'atelier de programmation Firebase App Check pour les plates-formes Apple. L'application de démarrage rapide DatabaseExample permet aux utilisateurs de se connecter et d'ajouter des posts à l'aide des fonctionnalités de Firebase Realtime Database.

Vous pouvez également adapter les étapes de cet atelier de programmation pour tester votre propre application.

Conditions préalables

Prérequis

  • Xcode 12.5 ou version ultérieure
  • Pour les tests App Attest :
  • Projet Firebase avec :
  • Avoir accès au projet Firebase associé à votre application, et être autorisé à utiliser et à gérer Remote Config, ainsi qu'à consulter le compte Google Analytics

2. Créer un fournisseur d'attestation personnalisé

Dans cette étape, nous allons créer une classe de fournisseur personnalisée pour fournir un jeton uniquement lorsque App Attest est activé. Remote Config s'appuie sur une instance d'application Firebase configurée. Le fournisseur personnalisé que vous implémentez à cette étape sert d'espace réservé pour terminer la configuration.

Pour effectuer les étapes suivantes, vous devez ajouter Firebase, FirebaseRemoteConfig et FirebaseAnalytics dans la section Frameworks, Libraries, and Embedded Content (Frameworks, bibliothèques et contenu intégré) de votre application dans Xcode. Pour obtenir un exemple, consultez l'atelier de programmation Firebase App Check pour les plates-formes Apple.

  1. Créez un fichier "MyAppCheckProvider" qui est une sous-classe de NSObject conforme au protocole AppCheckProvider.
  2. Incluez une méthode getToken() vide que vous remplirez plus tard.

Consultez l'exemple de code suivant pour la classe de fournisseur personnalisée avec une méthode getToken() vide.

// MyAppCheckProvider.swift

import Firebase
import FirebaseAnalytics
import FirebaseAppCheck
import FirebaseRemoteConfig

class MyAppCheckProvider: NSObject, AppCheckProvider {
  func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) {}
}

Pour instancier AppAttestProvider, vous devez transmettre une instance de FirebaseApp correspondante. Créez une propriété stockée pour celui-ci et acceptez-le comme paramètre d'initialiseur :

// MyAppCheckProvider.swift

import Firebase
import FirebaseAnalytics
import FirebaseAppCheck
import FirebaseRemoteConfig

class MyAppCheckProvider: NSObject, AppCheckProvider {
  // Firebase app instance served by the provider.
  let firebaseApp: FirebaseApp

  // The App Check provider factory should pass the FirebaseApp instance.
  init(app: FirebaseApp) {
    self.firebaseApp = app
    super.init()
  }

  func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) {}
}

Transmettre la demande de jeton au fournisseur App Attest

Vous avez maintenant tout ce qu'il faut pour transférer la demande de jeton au fournisseur App Attest dans votre méthode getToken().

Remarque : Pour en savoir plus sur la méthode getToken(), consultez la documentation de référence du framework FirebaseAppCheck.

Ajoutez le code suivant à votre méthode getToken() :

// MyAppCheckProvider.swift

import Firebase
import FirebaseAnalytics
import FirebaseAppCheck
import FirebaseRemoteConfig

class MyAppCheckProvider: NSObject, AppCheckProvider {
  // Firebase app instance served by the provider.
  let firebaseApp: FirebaseApp

  // The App Check provider factory should pass the FirebaseApp instance.
  init(app: FirebaseApp) {
    self.firebaseApp = app
    super.init()
  }

  private lazy var appAttestProvider = AppAttestProvider(app: firebaseApp)

  func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) {
    // Fetch App Attest flag from Remote Config
    let remoteConfig = RemoteConfig.remoteConfig(app: firebaseApp)
    remoteConfig.fetchAndActivate { remoteConfigStatus, error in
      // Get App Attest flag value
      let appAttestEnabled = remoteConfig.configValue(forKey: "AppAttestEnabled").boolValue

      guard appAttestEnabled else {
        // Skip attestation if App Attest is disabled. Another attestation
        // method like DeviceCheck may be used instead of just skipping.
        handler(nil, MyProviderError.appAttestIsDisabled)
        return
      }

      // Try to obtain an App Attest provider instance and fail if cannot
      guard let appAttestProvider = self.appAttestProvider else {
        handler(nil, MyProviderError.appAttestIsUnavailable)
        return
      }

      // If App Attest is enabled for the app instance, then forward the
      // Firebase App Check token request to the App Attest provider
      appAttestProvider.getToken(completion: handler)
    }
  }
}

enum MyProviderError: Error {
  case appAttestIsDisabled
  case appAttestIsUnavailable
  case unexpected(code: Int)
}

Le code précédent vérifie un paramètre booléen AppAttestEnabled Remote Config (ce paramètre Remote Config sera créé plus tard dans l'atelier de programmation). Si la valeur est "false", le code échoue, ce qui indique qu'App Check n'est pas déployé sur l'appareil actuel. Si la valeur est "true", le code tente d'obtenir un fournisseur App Attest et échoue si ce n'est pas possible. Si ces vérifications d'erreur sont réussies, le code transmet la demande de jeton au fournisseur App Attest.

Ajouter des événements Analytics

En ajoutant des événements Analytics, vous obtiendrez de meilleurs insights sur le succès du déploiement d'App Check. Analytics vous aidera à déterminer si App Attest doit être activé pour une audience plus large.

Enregistrez deux événements Analytics : AppAttestSuccess en cas de réussite et AppAttestFailure en cas d'échec. Ces deux événements Analytics peuvent vous aider à suivre le succès de votre déploiement App Check et à décider si un déploiement plus important doit être effectué.

func getToken(completion handler: @escaping (AppCheckToken?, Error?) -> Void) {
  // Fetch Remote Config.
  let remoteConfig = RemoteConfig.remoteConfig(app: firebaseApp)
  remoteConfig.fetchAndActivate { remoteConfigStatus, error in
    // Get App Attest flag value from Remote Config.
    let appAttestEnabled = remoteConfig.configValue(forKey: "AppAttestEnabled").boolValue

    guard appAttestEnabled else {
      // Skip attestation if App Attest is disabled. Another attestation
      // method like DeviceCheck may be used instead of just skipping.
      handler(nil, MyProviderError.appAttestIsDisabled)
      return
    }

    // Try to obtain an App Attest provider instance and fail otherwise.
    guard let appAttestProvider = self.appAttestProvider else {
      handler(nil, MyProviderError.appAttestIsUnavailable)
      return
    }

    // If App Attest is enabled for the app instance, then forward the
    // Firebase App Check token request to the App Attest provider.
    appAttestProvider.getToken { token, error in
      // Log an Analytics event to track attestation success rate.
      let appAttestEvent: String
      if (token != nil && error == nil) {
        appAttestEvent = "AppAttestSuccess"
      } else {
        appAttestEvent = "AppAttestFailure"
      }
      Analytics.logEvent(appAttestEvent, parameters: nil)

      // Pass the result to the handler
      handler(token, error)
    }
  }
}

3. Mettre à jour la classe Provider Factory

Après avoir implémenté la logique permettant de transférer la demande de jeton au fournisseur App Attest et ajouté des événements Analytics, vous devez mettre à jour MyAppCheckProviderFactory.class que vous avez créé dans l'atelier de programmation App Check pour les plates-formes Apple. Cette classe ciblera le fournisseur de débogage App Check pour les simulateurs, et votre fournisseur personnalisé dans le cas contraire.

Modifiez le code suivant dans la classe MyAppCheckProviderFactory que vous avez créée dans l'atelier de programmation Firebase App Check pour les plates-formes Apple :

// 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
      if #available(iOS 14.0, *) {
        // Use your custom App Attest provider on real devices.
        return MyAppCheckProvider(app: app)
      } else {
        return DeviceCheckProvider(app: app)
      }
      #endif
  }
}

Assurez-vous d'avoir défini AppCheckProviderFactory avant de configurer FirebaseApp :

// DatabaseExampleApp.swift

import SwiftUI
import Firebase
import FirebaseAppCheck

@main
struct DatabaseExampleApp: App {
  init() {
    AppCheck.setAppCheckProviderFactory(MyAppCheckProviderFactory())
    FirebaseApp.configure()
  }

  // ...
}

4. Ajouter un paramètre Remote Config dans la console Firebase

Vous allez maintenant ajouter le paramètre Remote Config AppAttestEnabled à la console Firebase . Votre méthode getToken nécessite ce paramètre.

Pour créer un paramètre Remote Config dans la console Firebase :

  1. Ouvrez Remote Config pour votre projet, puis cliquez sur Ajouter un paramètre. Si vous utilisez Remote Config pour la première fois, cliquez sur Créer une configuration.
  2. Dans le champ Nom du paramètre (clé), saisissez AppAttestEnabled.
  3. Dans le menu déroulant Type de données, sélectionnez Booléen.
  4. Dans le menu déroulant Valeur par défaut, sélectionnez false.

Créer un paramètre Remote Config dans la console Firebase

Avant de cliquer sur "Enregistrer", créez une valeur conditionnelle pour 10 % des utilisateurs :

  1. Cliquez sur Ajouter > Valeur conditionnelle > Créer une condition.
  2. Dans le champ Nom, saisissez un nom de condition.
  3. Sous S'applique si…, sélectionnez Utilisateur dans un centile aléatoire, <=, puis saisissez 10 dans le champ %.
  4. Cliquez sur Créer une condition.

Définir une condition Remote Config dans la console Firebase

Définissez la valeur conditionnelle sur true pour que l'attestation d'application soit déployée auprès de 10 % de vos utilisateurs.

  1. Définissez la valeur sur true pour la condition que vous venez de créer.
  2. Cliquez sur Enregistrer.

Examiner le paramètre Remote Config dans la console Firebase

Lorsque vous avez terminé, publiez les modifications apportées à Remote Config.

Tester le déploiement sur votre appareil

Pour tester les différentes valeurs de flag Remote Config sur votre appareil sans modifier le code de l'application, configurez un test sur le paramètre AppAttestEnabled en suivant le tutoriel Créer des tests Firebase Remote Config avec A/B Testing. La section du tutoriel Valider votre test sur un appareil de test explique comment attribuer différentes valeurs à votre appareil de test.

La dernière étape consiste à utiliser Google Analytics pour surveiller le succès du déploiement d'App Attest.

5. Vérifier la réussite du déploiement d'AppCheck

Vous pouvez mesurer le succès de votre déploiement dans le tableau de bord "Événements Analytics". Recherchez les événements AppAttestSuccess et AppAttestFailure. Il peut s'écouler jusqu'à 24 heures avant que les événements n'apparaissent dans le tableau de bord. Vous pouvez également activer le débogage et utiliser DebugView pour afficher plus rapidement les événements de débogage.

Vous pouvez également surveiller le tableau de bord Crashlytics pour détecter toute augmentation du taux d'erreur. Pour en savoir plus sur l'ajout de Crashlytics à votre application, consultez Premiers pas avec Firebase Crashlytics.

Lorsque vous voyez principalement des événements AppAttestSuccess et peu d'événements AppAttestFailure, cela signifie que vous pouvez augmenter le pourcentage d'utilisateurs pour lesquels App Attest est activé en modifiant la condition dans le paramètre Remote Config AppAttestEnabled.

Examiner les événements Analytics dans la console Firebase

Facultatif : Exploitez l'audience Google Analytics

Si vous souhaitez exploiter davantage l'événement Analytics AppAttestEnabled, vous pouvez créer une audience Analytics pour suivre les utilisateurs dont la valeur AppAttestEnabled est définie sur "true".

App Attest est sorti avec iOS 14.0. Il est possible que certains de vos utilisateurs n'utilisent pas cette version et ne soient donc pas éligibles à App Attest. Vous pouvez enregistrer un autre événement Analytics pour suivre ces utilisateurs, puis cibler cette audience pour une autre méthode d'attestation, comme DeviceCheck.

Facultatif : Utiliser Crashlytics pour surveiller les plantages

Pour mieux comprendre la stabilité de votre application lors du déploiement, utilisez Firebase Crashlytics pour surveiller les plantages et les erreurs non fatales.

6. Félicitations !

Vous avez déployé App Check avec Remote Config 🎉

Autres ressources :