1. 简介
您可以将 Firebase App Check 与 App Attest 搭配使用,以保护后端服务并验证发送到 Firebase 服务的请求是否来自真实的应用。
通常建议您逐步将用户纳入 App Attest 服务,以免达到配额限制。如需了解详情,请参阅 Apple 的“准备使用应用认证服务”文档。
如分阶段发布版本更新中所述,使用 Apple 的 App Store Connect 功能逐步发布应用更新有助于更顺利地推出 App Check。这是一个简单明了的解决方案。不过,分阶段发布应用版本更新后,您无法在不发布新应用版本的情况下控制已更新应用的发布或更改行为。
如需更好地控制 App Check 与 App Attest 的发布,一种方法是使用 Firebase Remote Config 一次为应用的一定比例的用户启用 App Check 与 App Attest。这有助于避免来自认证服务器的节流。您可以使用 Google Analytics 来观察发布对用户的影响。
学习内容
在此分步 Codelab 中,您将学习如何使用 Firebase Remote Config 为您的应用发布 App Check。
此 Codelab 使用的是基于 DatabaseExample 快速入门应用且与 Firebase App Check 集成的 Firebase 项目,如 “适用于 Apple 平台的 Firebase App Check”Codelab 中所述。借助 DatabaseExample 快速入门应用,用户可以使用 Firebase Realtime Database 的功能登录并添加帖子。
您还可以根据此 Codelab 中的步骤测试自己的应用。
前提条件
所需条件
- Xcode 12.5 或更高版本
- 对于 App Attest 测试:
- 一个 Apple 开发者账号,用于创建新的应用标识符
- 具有已启用 App Attest 功能的明确应用 ID 的应用。如果您需要有关此流程的帮助,请参阅注册应用 ID 和启用应用功能一文。
- 支持 App Attest 的 iOS/iPadOS 设备
- Firebase 项目,其中包含:
- 已配置的 iOS 应用(了解详情)
- 已启用 Google Analytics 、Remote Config 和 App Check
- 有权访问您应用的关联 Firebase 项目,并且有权创建和管理 Remote Config 以及查看 Google Analytics
2. 创建自定义认证提供程序
在此步骤中,我们将创建一个自定义提供程序类,以便仅在启用应用认证时提供令牌。Remote Config 依赖于已配置的 Firebase 应用实例,您在此步骤中实现的自定义提供程序充当完成配置的占位符。
若要完成以下步骤,您需要在 Xcode 中应用的 Frameworks, Libraries, and Embedded Content 部分中添加 Firebase
、FirebaseRemoteConfig
和 FirebaseAnalytics
。如需有关如何执行此操作的示例,请参阅 适用于 Apple 平台的 Firebase App Check Codelab。
- 创建一个文件“MyAppCheckProvider”,它是符合
AppCheckProvider
协议的NSObject
的子类。 - 添加一个空的
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 提供程序
现在,您已完成所有操作,可以将令牌请求转发到 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 参数将在本 Codelab 的后面部分创建)。如果值为 false,则代码会失败,表示 App Check 未在当前设备上发布。如果值为 true,代码会尝试获取应用认证提供程序,如果无法获取,则会失败。如果通过这些错误检查,代码会将令牌请求转发给应用认证提供程序。
添加 Google Analytics 事件
通过添加 Google Analytics 事件,您可以更好地了解 App Check 的发布效果。Google Analytics 有助于确定是否应为更多用户启用 App Attest。
记录两个 Google Analytics 事件:成功时记录 AppAttestSuccess,失败时记录 AppAttestFailure。这两个 Google 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 提供程序的逻辑并添加一些 Google Analytics 事件后,您需要更新在 App Check for Apple Platforms Codelab 中创建的 MyAppCheckProviderFactory.class
。对于模拟器,此类将定位到 App Check 调试提供程序;对于其他设备,则会定位到您的自定义提供程序。
在您在 “适用于 Apple 平台的 Firebase App Check”Codelab 中创建的 MyAppCheckProviderFactory
类中,修改以下代码:
// 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. 在 Firebase 控制台中添加 Remote Config 参数
现在,您将向 Firebase 控制台添加 Remote Config 参数 AppAttestEnabled。您的 getToken
方法需要此参数。
如需在 Firebase 控制台中创建 Remote Config 参数,请执行以下操作:
- 打开项目的 Remote Config,然后点击添加参数。如果您是首次使用 Remote Config,请点击创建配置。
- 在参数名称(键)字段中,输入
AppAttestEnabled
。 - 从数据类型下拉菜单中,选择布尔值。
- 从默认值下拉菜单中,选择 false。
在点击“保存”之前,为 10% 的用户创建一个条件值:
- 依次点击添加新内容 > 基于条件的值 > 创建新条件。
- 在名称字段中,输入条件名称。
- 在“如果满足以下条件,则应用”下,依次选择用户位于随机百分位数范围内、<=,然后在% 字段中输入 10。
- 点击创建条件。
将条件值设置为 true,以便将应用验证功能面向 10% 的用户发布。
- 将您刚刚创建的条件的值设置为 true。
- 点击保存。
完成后,发布 Remote Config 更改。
在设备上测试发布
如需在设备上测试不同的 Remote Config 标志值,而无需修改应用代码,请按照“使用 A/B Testing 创建 Firebase Remote Config 实验”教程中的说明,针对 AppAttestEnabled 参数配置实验。在“在测试设备上验证您的实验”部分,我们介绍了如何为测试设备分配不同的值。
最后一步是使用 Google Analytics 监控应用证明的发布成效。
5. 查看 AppCheck 的发布是否成功
您可以在 Google Analytics 事件信息中心衡量发布活动的成效。监控 AppAttestSuccess 和 AppAttestFailure 事件。事件最长可能需要 24 小时才会显示在信息中心内。或者,您也可以启用调试功能,并使用 DebugView 更快地查看调试事件。
您可以选择监控 Crashlytics 信息中心,以了解崩溃率是否有所增加。如需详细了解如何将 Crashlytics 添加到应用中,请参阅 Firebase Crashlytics 使用入门。
如果您看到的大部分是 AppAttestSuccess 事件,而 AppAttestFailure 事件很少,这是一个好兆头,表明您可以通过修改 Remote Config 参数 AppAttestEnabled 中的条件来提高启用应用验证的用户百分比。
可选:利用 Google Analytics 受众群体
如果您想进一步利用 AppAttestEnabled Google Analytics 事件,可以创建 Google Analytics 受众群体,以跟踪将 AppAttestEnabled 设置为 true 的用户。
App Attest 随 iOS 14.0 一起发布。您的部分用户可能未使用此版本,因此不符合使用应用认证的条件。您可以记录其他 Google Analytics 事件来跟踪这些用户,然后定位该受众群体以使用其他认证方法(例如 DeviceCheck)。
可选:使用 Crashlytics 监控崩溃
如需更好地了解应用在发布期间的稳定性,请使用 Firebase Crashlytics 监控崩溃和非严重错误。
6. 恭喜!
您已成功通过 Remote Config 发布 App Check 🎉