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

1. Введение

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

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

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

Один из способов лучше контролировать развёртывание 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 с разрешениями на создание и управление удаленной конфигурацией, а также на просмотр Google Analytics.

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

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

Чтобы выполнить следующие шаги, вам потребуется добавить Firebase , FirebaseRemoteConfig и FirebaseAnalytics в раздел «Фреймворки, библиотеки и встроенный контент» вашего приложения в 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 Attest и завершается ошибкой, если это невозможно. Если эти проверки на ошибки пройдены, код пересылает запрос на токен поставщику App Attest.

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

Добавляя события Analytics, вы получаете более точное представление об успешности внедрения 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. Обновите класс фабрики поставщиков.

После реализации логики пересылки запроса токена поставщику 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
  }
}

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

// DatabaseExampleApp.swift

import SwiftUI
import Firebase
import FirebaseAppCheck

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

  // ...
}

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

Теперь добавьте параметр удалённой конфигурации AppAttestEnabled в консоль Firebase. Этот параметр требуется для вашего метода getToken .

Чтобы создать параметр удаленной конфигурации в консоли Firebase:

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

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

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

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

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

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

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

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

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

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

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

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

5. Оцените успешность внедрения AppCheck.

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

При желании вы можете отслеживать увеличение частоты сбоев на панели управления Crashlytics. Подробнее о добавлении Crashlytics в приложение см. в статье «Начало работы с Firebase Crashlytics» .

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

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

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

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

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

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

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

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

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

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