Implemente gradualmente Firebase App Check con Firebase Remote Config

1. Introducción

Puede usar Firebase App Check con App Attest para proteger sus servicios backend y verificar que las solicitudes a los servicios de Firebase provengan de su aplicación auténtica.

Por lo general, se recomienda incorporar a los usuarios gradualmente al servicio App Attest para evitar alcanzar los límites de cuota. Para obtener más información, consulte la documentación de Apple " Preparing to Use the App Attest Service ".

La capacidad de publicar actualizaciones de aplicaciones de forma incremental utilizando la función App Store Connect de Apple, como se describe en " Publicación de una actualización de versión en fases ", puede hacer que la implementación de App Check sea más fluida. Esta es una solución simple y sencilla. Sin embargo, publicar una actualización de la versión de la aplicación por etapas no le permite controlar la implementación o cambiar el comportamiento de las aplicaciones actualizadas existentes sin publicar una nueva versión de la aplicación.

Una forma de tener más control sobre el lanzamiento de App Check with App Attest es usar Firebase Remote Config para habilitar App Check with App Attest para un porcentaje de los usuarios de su aplicación a la vez. Esto puede ayudar a evitar la limitación de los servidores de atestación. Google Analytics se puede utilizar para observar el impacto del lanzamiento en los usuarios.

lo que aprenderás

En este laboratorio de código de varios pasos, aprenderá a usar Firebase Remote Config para implementar App Check para su aplicación.

Este codelab usa un proyecto de Firebase basado en la aplicación de inicio rápido DatabaseExample e integrado con Firebase App Check, como se describe en Firebase App Check for Apple Platforms codelab . La aplicación de inicio rápido DatabaseExample permite a los usuarios iniciar sesión y agregar publicaciones utilizando las funciones de Firebase Realtime Database.

También puede adaptar los pasos de este laboratorio de código para probar su propia aplicación.

requisitos previos

Lo que necesitarás

  • Xcode 12.5+
  • Para las pruebas de atestación de aplicaciones:
  • Proyecto de Firebase con:
  • Acceso al proyecto de Firebase asociado a su aplicación, con permisos para crear y administrar Remote Config y para ver Google Analytics

2. Cree un proveedor de atestación personalizado

En este paso, crearemos una clase de proveedor personalizada para proporcionar un token solo cuando App Attest esté habilitado. Remote Config se basa en una instancia de aplicación de Firebase configurada, y el proveedor personalizado que implementa en este paso actúa como marcador de posición para finalizar la configuración.

Para completar los siguientes pasos, deberá agregar Firebase , FirebaseRemoteConfig y FirebaseAnalytics en la sección Frameworks, Libraries and Embedded Content de su aplicación en Xcode. Para ver un ejemplo de cómo hacer esto, consulte la verificación de la aplicación Firebase para el codelab de las plataformas de Apple .

  1. Cree un archivo " MyAppCheckProvider " que sea una subclase de NSObject conforme al protocolo AppCheckProvider .
  2. Incluya un método getToken() vacío que completará más adelante.

Consulte el siguiente código de ejemplo para la clase de proveedor personalizado con el método getToken() vacío.

// MyAppCheckProvider.swift

import Firebase
import FirebaseAnalytics
import FirebaseAppCheck
import FirebaseRemoteConfig

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

Para crear una instancia AppAttestProvider , deberá pasar una instancia de la FirebaseApp correspondiente. Cree una propiedad almacenada para él y acéptelo como un parámetro de inicialización:

// 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) {}
}

Reenviar la solicitud de token al proveedor de App Attest

Ahora tiene todo lo necesario para reenviar la solicitud de token al proveedor de App Attest en su método getToken() .

Nota: Obtén más información sobre el método getToken() en la Referencia del marco de FirebaseAppCheck .

Agrega el siguiente código a tu método 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)
}

El código anterior comprueba un parámetro booleano AppAttestEnabled de Remote Config (este parámetro de Remote Config se creará más adelante en el laboratorio de código). Si el valor es falso, el código falla, lo que indica que App Check no se implementó en el dispositivo actual. Si el valor es verdadero, el código intenta obtener un proveedor de Attest de aplicación y falla si no puede. Si se pasan estas comprobaciones de errores, el código reenviará la solicitud de token al proveedor de Attest de la aplicación.

Añadir eventos de Analytics

Al agregar eventos de Analytics, obtiene mejores perspectivas sobre el éxito de la implementación de App Check. Analytics ayudará a determinar si App Attest debe habilitarse para una audiencia más amplia.

Registre dos eventos de Analytics: AppAttestSuccess en caso de éxito y AppAttestFailure en caso de error. Estos dos eventos de Analytics pueden ayudar a rastrear el éxito de su lanzamiento de App Check y ayudarlo a decidir si debe continuar con un lanzamiento más grande.

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. Actualice la clase Provider Factory

Después de implementar la lógica para reenviar la solicitud de token al proveedor de Attest de la aplicación y agregar algunos eventos de Analytics, debe actualizar MyAppCheckProviderFactory.class que creó en el codelab de App Check para Apple Platforms . Esta clase se dirigirá al proveedor de depuración de App Check para simuladores y, de lo contrario, se dirigirá a su proveedor personalizado.

Edite el siguiente código en la clase MyAppCheckProviderFactory que creó en el Codelab de Firebase App Check para plataformas 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
  }
}

Confirma que has configurado AppCheckProviderFactory antes de configurar FirebaseApp :

// DatabaseExampleApp.swift

import SwiftUI
import Firebase
import FirebaseAppCheck

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

  // ...
}

4. Agregue un parámetro de configuración remota en la consola de Firebase

Ahora agregará el parámetro AppAttestEnabled de Remote Config a Firebase console. Su método getToken requiere este parámetro.

Para crear un parámetro de configuración remota en la consola de Firebase:

  1. Abra Remote Config para su proyecto y haga clic en Agregar parámetro . Si es la primera vez que usa Remote Config, haga clic en Crear configuración .
  2. En el campo Nombre del parámetro (clave) , ingrese AppAttestEnabled .
  3. En el menú desplegable Tipo de datos , seleccione Booleano .
  4. En el menú desplegable Valor predeterminado , seleccione false .

Crear un parámetro de configuración remota en la consola de Firebase

Antes de hacer clic en Guardar, cree un valor condicional para el 10 % de los usuarios:

  1. Haga clic en Agregar nuevo > Valor condicional > Crear nueva condición .
  2. En el campo Nombre , ingrese un nombre de condición.
  3. En Se aplica si... , seleccione Usuario en percentil aleatorio , <= y luego ingrese 10 en el campo % .
  4. Haga clic en Crear condición .

Definición de una condición de configuración remota en Firebase console

Establezca el valor condicional en verdadero para que App Attest se implemente en el 10 % de sus usuarios.

  1. Establezca el valor en verdadero para la condición que acaba de crear.
  2. Haga clic en Guardar .

Revisando el parámetro Remote Config en Firebase console

Cuando haya terminado, publique los cambios de configuración remota.

Pruebe la implementación en su dispositivo

Para probar los diferentes valores de marca de Remote Config en su dispositivo sin modificar el código de la aplicación, configure un experimento en el parámetro AppAttestEnabled siguiendo el tutorial Crear experimentos de Firebase Remote Config con pruebas A/B . La sección del tutorial " Valide su experimento en un dispositivo de prueba " explica cómo asignar diferentes valores para su dispositivo de prueba.

El paso final es usar Google Analytics para monitorear el éxito de su lanzamiento de App Attest.

5. Revise el éxito de su implementación de AppCheck

Puede medir el éxito de su lanzamiento en el panel de control de eventos de Analytics. Observe los eventos AppAttestSuccess y AppAttestFailure . Puede tomar hasta 24 horas para ver los eventos en el tablero. Como alternativa, puede habilitar la depuración y usar DebugView para ver los eventos de depuración más rápidamente.

Opcionalmente, puede monitorear el panel de control de Crashlytics para detectar aumentos en las tasas de fallas. Para obtener más información sobre cómo agregar Crashlytics a su aplicación, consulte Primeros pasos con Firebase Crashlytics .

Una vez que vea la mayoría de los eventos AppAttestSuccess y pocos eventos AppAttestFailure , es una buena señal de que puede aumentar el porcentaje de usuarios con App Attest habilitado modificando la condición en el parámetro de Remote Config AppAttestEnabled .

Revisar eventos de Analytics en Firebase console

Opcional: Aproveche la audiencia de Google Analytics

Si desea aprovechar aún más el evento de análisis AppAttestEnabled , puede crear una audiencia de análisis para realizar un seguimiento de los usuarios con AppAttestEnabled establecido en verdadero.

App Attest se lanzó con iOS 14.0. Es posible que algunos de sus usuarios no estén en esta versión y, por lo tanto, no sean elegibles para App Attest. Puede registrar otro evento de Analytics para rastrear a estos usuarios y luego dirigirse a esa audiencia para otro método de atestación, como DeviceCheck .

Opcional: use Crashlytics para monitorear fallas

Para comprender mejor la estabilidad de su aplicación durante el lanzamiento, use Firebase Crashlytics para monitorear los bloqueos y los no fatales.

6. ¡Felicitaciones!

Ejecutaste con éxito App Check con Remote Config 🎉

Recursos adicionales: