Implemente gradualmente o Firebase App Check usando o Firebase Remote Config

1. Introdução

Você pode usar o Firebase App Check com o App Attest para proteger seus serviços de back-end e verificar se as solicitações aos serviços do Firebase vêm de seu aplicativo autêntico.

Geralmente, é recomendável integrar os usuários gradualmente ao serviço App Attest para evitar atingir os limites de cota. Para obter mais informações, consulte a documentação " Preparando para usar o App Attest Service " da Apple.

A capacidade de lançar atualizações de aplicativos de forma incremental usando o recurso App Store Connect da Apple, conforme descrito em " Liberando uma atualização de versão em fases ", pode facilitar a implementação do App Check. Esta é uma solução direta e simples. No entanto, liberar uma atualização de versão do aplicativo em etapas não permite que você controle o lançamento ou altere o comportamento de aplicativos atualizados existentes sem publicar uma nova versão do aplicativo.

Uma maneira de ter mais controle sobre a implementação do App Check com App Attest é usar o Firebase Remote Config para habilitar o App Check com App Attest para uma porcentagem dos usuários de seu aplicativo por vez. Isso pode ajudar a evitar a limitação dos servidores de atestado. O Google Analytics pode ser usado para observar o impacto do lançamento nos usuários.

O que você aprenderá

Neste codelab de várias etapas, você aprenderá a usar o Firebase Remote Config para implantar o App Check em seu app.

Este codelab usa um projeto Firebase baseado no app de início rápido DatabaseExample e integrado ao Firebase App Check, conforme descrito no codelab Firebase App Check para plataformas Apple . O aplicativo de início rápido DatabaseExample permite que os usuários façam login e adicionem postagens usando os recursos do Firebase Realtime Database.

Você também pode adaptar as etapas deste codelab para testar seu próprio app.

Pré-requisitos

O que você precisará

  • Código X 12.5+
  • Para teste de App Attest:
  • Projeto Firebase com:
  • Acesso ao projeto Firebase associado ao seu aplicativo, com permissões para criar e gerenciar Configuração remota e visualizar o Google Analytics

2. Crie um provedor de atestado personalizado

Nesta etapa, criaremos uma classe de provedor personalizada para fornecer um token somente quando o App Attest estiver habilitado. Configuração remota depende de uma instância configurada do aplicativo Firebase, e o provedor personalizado que você implementa nesta etapa atua como o marcador de posição para concluir a configuração.

Para concluir as etapas a seguir, você precisará adicionar Firebase , FirebaseRemoteConfig e FirebaseAnalytics na seção Frameworks, Libraries e Embedded Content de seu aplicativo no Xcode. Para ver um exemplo de como fazer isso, consulte o codelab Firebase App check for Apple Platforms .

  1. Crie um arquivo " MyAppCheckProvider " que é uma subclasse de NSObject em conformidade com o protocolo AppCheckProvider .
  2. Inclua um método getToken() vazio que você preencherá mais tarde.

Consulte o código de exemplo a seguir para a classe de provedor customizada com o método getToken() vazio.

// MyAppCheckProvider.swift

import Firebase
import FirebaseAnalytics
import FirebaseAppCheck
import FirebaseRemoteConfig

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

Para instanciar AppAttestProvider , você precisará passar uma instância do FirebaseApp correspondente. Crie uma propriedade armazenada para ela e aceite-a como um parâmetro inicializador:

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

Encaminhe a solicitação de token para o provedor App Attest

Agora você tem tudo para encaminhar a solicitação de token para o provedor App Attest em seu método getToken() .

Observação: saiba mais sobre o método getToken() na Referência da estrutura FirebaseAppCheck .

Adicione o seguinte código ao seu 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)
}

O código anterior verifica um parâmetro booleano do Remote Config AppAttestEnabled (esse parâmetro do Remote Config será criado posteriormente no codelab). Se o valor for falso, o código falhará, indicando que o App Check não foi implantado no dispositivo atual. Se o valor for true, o código tentará obter um provedor App Attest e falhará se não conseguir. Se essas verificações de erro forem aprovadas, o código encaminhará a solicitação de token para o provedor App Attest.

Adicionar eventos do Analytics

Ao adicionar eventos do Analytics, você obtém insights melhores sobre o sucesso da implementação do App Check. O Analytics ajudará a determinar se o App Attest deve ser ativado para um público maior.

Registre dois eventos do Analytics: AppAttestSuccess em caso de sucesso e AppAttestFailure em caso de falha. Esses dois eventos do Analytics podem ajudar a acompanhar o sucesso do lançamento do App Check e a decidir se um lançamento maior deve prosseguir.

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. Atualize a classe Provider Factory

Depois de implementar a lógica para encaminhar a solicitação de token para o provedor App Attest e adicionar alguns eventos Analytics, você precisa atualizar MyAppCheckProviderFactory.class que você criou no codelab App Check for Apple Platforms . Esta classe terá como alvo o provedor de depuração App Check para simuladores e, caso contrário, terá como alvo seu provedor personalizado.

Edite o seguinte código na classe MyAppCheckProviderFactory que você criou no codelab 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
  }
}

Confirme se você definiu o AppCheckProviderFactory antes de configurar FirebaseApp :

// DatabaseExampleApp.swift

import SwiftUI
import Firebase
import FirebaseAppCheck

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

  // ...
}

4. Adicione um parâmetro de configuração remota no console do Firebase

Agora você adicionará o parâmetro AppAttestEnabled do Remote Config ao console do Firebase . Seu método getToken requer este parâmetro.

Para criar um parâmetro de configuração remota no console do Firebase:

  1. Abra Configuração remota para seu projeto e clique em Adicionar parâmetro . Se esta for a primeira vez que você usa o Remote Config, clique em Create configuration .
  2. No campo Nome do parâmetro (chave) , insira AppAttestEnabled .
  3. No menu suspenso Tipo de dados , selecione Boolean .
  4. No menu suspenso Valor padrão , selecione false .

Criando parâmetro de configuração remota no console do Firebase

Antes de clicar em Salvar, crie um valor condicional para 10% dos usuários:

  1. Clique em Adicionar novo > Valor condicional > Criar nova condição .
  2. No campo Nome , insira um nome de condição.
  3. Em Aplica-se se... , selecione Usuário em percentil aleatório , <= e insira 10 no campo % .
  4. Clique em Criar condição .

Definindo uma condição de configuração remota no console do Firebase

Defina o valor condicional como true para que o App Attest seja distribuído para 10% de seus usuários.

  1. Defina o valor como true para a condição que você acabou de criar.
  2. Clique em Salvar .

Revisando o parâmetro Remote Config no Firebase console

Quando terminar, publique as alterações do Remote Config.

Teste o lançamento em seu dispositivo

Para testar os diferentes valores de sinalização do Remote Config em seu dispositivo sem modificar o código do aplicativo, configure um experimento no parâmetro AppAttestEnabled seguindo o tutorial Create Firebase Remote Config Experiments with A/B Testing . A seção do tutorial " Valide seu experimento em um dispositivo de teste " explica como atribuir diferentes valores para seu dispositivo de teste.

A etapa final é usar o Google Analytics para monitorar o sucesso da implantação do App Attest.

5. Revise o sucesso de sua implementação do AppCheck

Você pode medir o sucesso de sua implementação no painel Analytics Events. Observe os eventos AppAttestSuccess e AppAttestFailure . Pode levar até 24 horas para ver os eventos no painel. Como alternativa, você pode habilitar a depuração e usar o DebugView para ver os eventos de depuração mais rapidamente.

Opcionalmente, você pode monitorar o painel do Crashlytics para aumentos nas taxas de falhas. Para obter mais informações sobre como adicionar o Crashlytics ao seu aplicativo, consulte Introdução ao Firebase Crashlytics .

Depois de ver principalmente eventos AppAttestSuccess e poucos eventos AppAttestFailure , é um bom sinal de que você pode aumentar a porcentagem de usuários com App Attest ativado modificando a condição no parâmetro AppAttestEnabled do Remote Config.

Revisão de eventos do Analytics no console do Firebase

Opcional: aproveite o público-alvo do Google Analytics

Se quiser aproveitar ainda mais o evento AppAttestEnabled Analytics, você pode criar um Analytics Audience para rastrear usuários com AppAttestEnabled definido como true.

App Attest foi lançado com iOS 14.0. Alguns de seus usuários podem não estar nesta versão e, portanto, não qualificados para o App Attest. Você pode registrar outro evento do Analytics para rastrear esses usuários e, em seguida, direcionar esse público para outro método de atestado, como DeviceCheck .

Opcional: use o Crashlytics para monitorar falhas

Para entender melhor a estabilidade do seu aplicativo durante o lançamento, use o Firebase Crashlytics para monitorar falhas e não fatais.

6. Parabéns!

Você implementou com sucesso o App Check com Remote Config 🎉

Recursos adicionais: