Постепенно развертывайте проверку приложений Firebase с помощью Firebase Remote Config.

1. Введение

Вы можете использовать Firebase App Check с App Attest для защиты своих серверных служб, чтобы убедиться, что запросы к службам Firebase поступают от вашего подлинного приложения.

Как правило, рекомендуется постепенно подключать пользователей к сервису App Attest, чтобы избежать превышения лимитов квот. Для получения дополнительной информации см. документацию Apple « Подготовка к использованию сервиса App Attest ».

Возможность поэтапного выпуска обновлений приложений с помощью функции App Store Connect от Apple, как описано в статье « Поэтапный выпуск обновлений версий », может упростить процесс проверки приложений App Check. Это простое и понятное решение. Однако поэтапный выпуск обновлений версий приложений не позволяет контролировать процесс или изменять поведение существующих обновленных приложений без публикации новой версии.

Один из способов лучше контролировать процесс развертывания проверки приложений с помощью App Check with App Attest — использовать Firebase Remote Config для включения проверки приложений с помощью App Check with App Attest для определенного процента пользователей вашего приложения за раз. Это может помочь избежать ограничения скорости со стороны серверов аттестации. Для отслеживания влияния развертывания на пользователей можно использовать Google Analytics.

Что вы узнаете

В этом пошаговом практическом занятии вы узнаете, как использовать Firebase Remote Config для развертывания App Check для вашего приложения.

В этом практическом занятии используется проект Firebase, основанный на быстром стартовом приложении DatabaseExample и интегрированный с Firebase App Check, как описано в практическом занятии Firebase App Check для платформ Apple . Быстрое стартовое приложение DatabaseExample позволяет пользователям входить в систему и добавлять сообщения, используя возможности Firebase Realtime Database.

Вы также можете адаптировать шаги из этого практического руководства для тестирования собственного приложения.

Предварительные требования

Что вам понадобится

  • Xcode 12.5+
  • Для тестирования App Attest:
  • Проект Firebase, включающий:
  • Доступ к связанному с вашим приложением проекту Firebase, с разрешениями на создание и управление удаленной конфигурацией (Remote Config) и просмотр Google Analytics.

2. Создайте собственный поставщик аттестации.

На этом шаге мы создадим пользовательский класс-провайдер, который будет предоставлять токен только тогда, когда включена функция App Attest. Remote Config использует настроенный экземпляр приложения Firebase, а пользовательский провайдер, реализованный на этом шаге, выступает в качестве заполнителя для завершения настройки.

Для выполнения следующих шагов вам потребуется добавить Firebase , FirebaseRemoteConfig и FirebaseAnalytics в раздел Frameworks, Libraries и Embedded Content вашего приложения в Xcode. Пример того, как это сделать, можно найти в руководстве по проверке приложений Firebase для платформ Apple .

  1. Создайте файл " MyAppCheckProvider ", являющийся подклассом NSObject , соответствующим протоколу AppCheckProvider .
  2. Добавьте пустой метод getToken() , который вы заполните позже.

См. следующий пример кода для пользовательского класса поставщика с пустым методом getToken() .

// MyAppCheckProvider.swift

import Firebase
import FirebaseAnalytics
import FirebaseAppCheck
import FirebaseRemoteConfig

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

Для создания экземпляра AppAttestProvider вам потребуется передать экземпляр соответствующего FirebaseApp . Создайте для него хранимое свойство и примите его в качестве параметра инициализации:

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

Перешлите запрос на получение токена поставщику App Attest.

Теперь у вас есть все необходимое, чтобы перенаправить запрос на получение токена поставщику App Attest в методе getToken() .

Примечание: Подробнее о методе getToken() можно узнать в справочнике по фреймворку FirebaseAppCheck .

Добавьте следующий код в метод 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)
}

Предыдущий код проверяет логический параметр Remote Config AppAttestEnabled (этот параметр Remote Config будет создан позже в практическом задании). Если значение равно false, код завершается с ошибкой, указывая на то, что проверка приложений не выполняется на текущем устройстве. Если значение равно true, код пытается получить поставщика проверки приложений и завершается с ошибкой, если это не удается. Если эти проверки на ошибки пройдены успешно, код перенаправит запрос токена поставщику проверки приложений.

Добавить события аналитики

Добавление событий аналитики позволит получить более полное представление об успешности развертывания App Check. Аналитика поможет определить, следует ли включить App Attest для более широкой аудитории.

Регистрируйте два события Analytics: AppAttestSuccess при успешном выполнении и AppAttestFailure при неудачном выполнении. Эти два события Analytics помогут отслеживать успешность развертывания App Check и помогут решить, следует ли проводить более масштабное развертывание.

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. Обновите класс Provider Factory.

После того, как вы реализовали логику пересылки запроса токена поставщику App Attest и добавили несколько событий Analytics, вам необходимо обновить класс MyAppCheckProviderFactory.class , который вы создали в практическом задании по проверке приложений для платформ Apple . Этот класс будет ориентирован на отладочный поставщик App Check для симуляторов, а в остальных случаях — на ваш собственный поставщик.

Отредактируйте следующий код в классе MyAppCheckProviderFactory , который вы создали в практическом задании по Firebase App Check для платформ 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
  }
}

Перед настройкой FirebaseApp убедитесь, что вы установили AppCheckProviderFactory :

// DatabaseExampleApp.swift

import SwiftUI
import Firebase
import FirebaseAppCheck

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

  // ...
}

4. Добавьте параметр Remote Config в консоль Firebase.

Теперь добавьте параметр Remote Config AppAttestEnabled в консоль Firebase. Для работы вашего метода getToken этот параметр необходим.

Чтобы создать параметр Remote Config в консоли Firebase:

  1. Откройте Remote Config для вашего проекта и нажмите «Добавить параметр» . Если вы используете Remote Config впервые, нажмите «Создать конфигурацию» .
  2. В поле «Имя параметра (ключ)» введите AppAttestEnabled .
  3. В раскрывающемся списке «Тип данных» выберите «Логический» .
  4. В раскрывающемся списке «Значение по умолчанию» выберите «false» .

Создание параметра удаленной конфигурации в консоли Firebase

Перед нажатием кнопки «Сохранить» создайте условное значение для 10% пользователей:

  1. Нажмите «Добавить новое» > «Условное значение» > «Создать новое условие» .
  2. В поле «Имя» введите название условия.
  3. В разделе «Применяется, если...» выберите «Пользователь в случайном процентиле» , <= , а затем введите 10 в поле % .
  4. Нажмите «Создать условие» .

Определение условия удаленной конфигурации в консоли Firebase

Установите для параметра условия значение true , чтобы проверка App Attest была проведена для 10% ваших пользователей.

  1. Установите для созданного вами условия значение true .
  2. Нажмите « Сохранить ».

Проверка параметра Remote Config в консоли Firebase.

После завершения опубликуйте изменения в удаленной конфигурации.

Проверьте развертывание на своем устройстве.

Чтобы протестировать различные значения флагов Remote Config на вашем устройстве без изменения кода приложения, настройте эксперимент для параметра AppAttestEnabled, следуя руководству по созданию экспериментов Firebase Remote Config с A/B-тестированием . В разделе руководства « Проверка эксперимента на тестовом устройстве » объясняется, как назначить различные значения для вашего тестового устройства.

Последний шаг — использование Google Analytics для отслеживания успешности развертывания вашей программы App Attest.

5. Проанализируйте успешность внедрения AppCheck.

Успешность развертывания можно оценить на панели мониторинга «События аналитики». Следите за событиями AppAttestSuccess и AppAttestFailure . Для отображения событий на панели мониторинга может потребоваться до 24 часов. В качестве альтернативы можно включить отладку и использовать DebugView для более быстрого просмотра событий отладки.

При желании вы можете отслеживать увеличение количества сбоев на панели мониторинга Crashlytics. Для получения дополнительной информации о добавлении Crashlytics в ваше приложение см. раздел «Начало работы с Firebase Crashlytics» .

Если вы видите преимущественно события AppAttestSuccess и лишь небольшое количество событий AppAttestFailure , это хороший знак того, что вы можете увеличить процент пользователей с включенной проверкой приложений, изменив условие в параметре удаленной конфигурации AppAttestEnabled .

Просмотр событий аналитики в консоли Firebase

Дополнительно: используйте аудиторию Google Analytics.

Если вы хотите более эффективно использовать событие AppAttestEnabled в аналитике, вы можете создать аудиторию аналитики для отслеживания пользователей, у которых для параметра AppAttestEnabled установлено значение true.

Функция App Attest была выпущена вместе с iOS 14.0. Некоторые из ваших пользователей могут не использовать эту версию и, следовательно, не иметь права на App Attest. Вы можете зарегистрировать другое событие Analytics для отслеживания этих пользователей, а затем нацелить эту аудиторию на другой метод аттестации, например, DeviceCheck .

Дополнительно: используйте Crashlytics для мониторинга сбоев.

Для лучшего понимания стабильности вашего приложения во время развертывания используйте Firebase Crashlytics для мониторинга сбоев и некритических ошибок.

6. Поздравляем!

Вы успешно развернули проверку приложений с помощью удаленной конфигурации 🎉

Дополнительные ресурсы: