使用 App Check 保护 API 密钥的安全
Firebase App Check 可通过阻止来自合法应用以外来源的流量,为您的应用对 Google Maps Platform 的调用提供保护。为此,它会检查来自 App Attest 等证明提供方的令牌。将应用与 App Check 集成有助于防范恶意请求,因此您无需为未经授权的 API 调用付费。
App Check 是否适合我?
在大多数情况下,建议使用 App Check,但在以下情况下,不需要或不支持 App Check:
- 您使用的是原始 Places SDK。App Check 仅支持 Places SDK(新)。
- 非公开应用或实验性应用。如果您的应用无法公开访问,则不需要使用 App Check。
- 如果您的应用仅用于服务器到服务器的通信,则无需使用 App Check。不过,如果与 GMP 通信的服务器由公共客户端(例如移动应用)使用,请考虑使用 App Check 保护该服务器,而不是使用 GMP。
- App Check 推荐的证明提供程序无法在被证明提供程序视为存在安全风险或不可信的设备上运行。如果您需要支持此类设备,可以部署自定义认证服务。如需了解详情,请参阅说明。
实现步骤概览
概括来讲,您需要按照以下步骤将应用与 App Check 集成:
- 将 Firebase 添加到您的应用。
- 添加并初始化 App Check 库。
- 将令牌提供程序添加到您的应用。
- 初始化 Places API 和 App Check API。
- 启用调试功能。
- 监控应用请求并决定是否强制执行。
与 App Check 集成后,您将能够在 Firebase 控制台中查看后端流量指标。这些指标可按请求是否附带有效的 App Check 令牌来细分请求。如需了解详情,请参阅 Firebase App Check 文档。
当您确定大多数请求来自合法来源,并且用户已更新到包含 App Check 实现的最新版应用后,即可启用强制执行。启用强制执行后,App Check 会拒绝所有没有有效 App Check 令牌的流量。
规划 App Check 集成时的注意事项
在规划集成时,请考虑以下事项:
我们推荐的证明提供方 Device Check 或 App Attest 受 Apple 所设配额和限制的约束。
您可以选择使用自定义证明提供方,不过这属于高级使用情形。如需了解详情,请参阅 Firebase App Check 文档。
-
您的应用的用户在启动时会遇到一些延迟。不过,之后任何定期重新认证都将在后台进行,用户应该不会再遇到任何延迟。启动时的确切延迟时间取决于您选择的证明提供方。
App Check 令牌的有效时长(即存留时间或 TTL)决定了重新证明的频率。您可以在 Firebase 控制台中配置此时长。当大约一半的 TTL 已过时,系统会重新进行证明。如需了解详情,请参阅您的证明提供方的 Firebase 文档。
将应用与 App Check 集成
前提条件和要求
- 已安装 Places SDK 9.2 版或更高版本的应用。
- 应用的软件包 ID。
- 您在 Apple Member Center 的“会员”下看到的团队 ID。
- 如果您计划使用设备检查,则需要私钥文件和密钥 ID。
- 您必须是 Cloud 控制台中相应应用的所有者。
- 您需要从 Cloud 控制台获取应用的相应项目 ID
第 1 步:将 Firebase 添加到您的应用
按照 Firebase 开发者文档中的说明将 Firebase 添加到您的应用。
注册应用后,您会获得一个配置文件 GoogleService-Info.plist
。将此文件(未经修改)添加到应用的根级目录中。
Places Swift SDK for iOS
import FirebaseCore import FirebaseAppCheck import GooglePlacesSwift
Swift
import FirebaseCore import FirebaseAppCheck import GooglePlaces
Objective-C
@import FirebaseCore; @import FirebaseAppCheck; @import GooglePlaces;
第 2 步:添加 App Check 库并初始化 App Check
Firebase 针对每个默认证明提供方提供了相关说明。这些说明将向您展示如何设置 Firebase 项目并将 App Check 库添加到您的应用。请按照提供的代码示例初始化 App Check。
- 按照 Firebase 说明添加 App Check 库:
- 初始化 App Check。
- 如果您使用的是 App Attest,请参阅 Firebase 开发者文档中的 App Attest 部分。
按照 Firebase App Check 说明创建
AppCheckProviderFactory
的实现,并将其添加到AppDelegate
文件中。Places Swift SDK for iOS
let providerFactory = YourAppCheckProviderFactory() AppCheck.setAppCheckProviderFactory(providerFactory)
Swift
let providerFactory = YourAppCheckProviderFactory() AppCheck.setAppCheckProviderFactory(providerFactory)
Objective-C
YourAppCheckProviderFactory *providerFactory = [[YourAppCheckProviderFactory alloc] init]; [FIRAppCheck setAppCheckProviderFactory:providerFactory];
- 如果您使用的是设备检查,请将以下内容添加到
AppDelegate
中:Places Swift SDK for iOS
AppCheck.setAppCheckProviderFactory(DeviceCheckProviderFactory())
Swift
AppCheck.setAppCheckProviderFactory(DeviceCheckProviderFactory())
Objective-C
[FIRAppCheck setAppCheckProviderFactory:providerFactory];
- 如果您使用的是 App Attest,请参阅 Firebase 开发者文档中的 App Attest 部分。
第 3 步:添加令牌提供程序
在应用的根级别创建一个名为 AppCheckTokenProvider
的文件(如果您使用的是 Objective-C,则创建两个名为 AppCheckTokenProvider.h
和 AppCheckTokenProvider.m
的文件)。
添加以下 import 语句和类定义:
Places Swift SDK for iOS
// AppCheckTokenProvider.swift import FirebaseAppCheck import Foundation import GooglePlacesSwift struct TokenProvider: AppCheckTokenProvider { func fetchAppCheckToken() async throws -> String { return try await AppCheck.appCheck().token(forcingRefresh: false).token } }
Swift
// AppCheckTokenProvider.swift import FirebaseAppCheck import Foundation import GooglePlaces class AppCheckTokenProvider: NSObject, GMSPlacesAppCheckTokenProvider { func fetchAppCheckToken() async throws -> String { return try await AppCheck.appCheck().token(forcingRefresh: false).token } }
Objective-C
// AppCheckTokenProvider.h @import Foundation; @import GooglePlaces; @interface AppCheckTokenProvider : NSObject <GMSPlacesAppCheckTokenProvider> @end // AppCheckTokenProvider.m #import "AppCheckTokenProvider.h" @import FirebaseAppCheck; @implementation AppCheckTokenProvider - (void)fetchAppCheckTokenWithCompletion:(nonnull GMSAppCheckTokenCompletion)completion { [[FIRAppCheck appCheck] tokenForcingRefresh:NO completion:^(FIRAppCheckToken *_Nullable token, NSError *_Nullable error) { if (token) { completion(token.token, nil); } else { completion(nil, error); } }]; } @end
第 4 步:初始化 Places API 和 App Check API
- 在
AppDelegate
文件中,初始化 Places API:Places Swift SDK for iOS
PlacesClient.provideAPIKey("YOUR_API_KEY")
Swift
GMSPlacesClient.provideAPIKey("YOUR_API_KEY")
Objective-C
[GMSPlacesClient provideAPIKey:@"YOUR_API_KEY"];
- 然后,初始化 App Check API:
Places Swift SDK for iOS
PlacesClient.setAppCheckTokenProvider(AppCheckTokenProvider())
Swift
GMSPlacesClient.setAppCheckTokenProvider(AppCheckTokenProvider())
Objective-C
[GMSPlacesClient setAppCheckTokenProvider:[[AppCheckTokenProvider alloc] init]];
第 5 步:启用调试功能(可选)
如果您想在本地开发和测试应用,或在持续集成 (CI) 环境中运行应用,可以创建应用的调试 build,该 build 使用调试密钥来获取有效的 App Check 令牌。这样一来,您就可以避免在调试 build 中使用真实的证明提供方。
如需在模拟器中或在测试设备上测试应用,请执行以下操作:
创建并设置 App Check 调试提供方工厂。
此代码示例同时处理调试和生产场景:Places Swift SDK for iOS
#if targetEnvironment(simulator) let providerFactory = AppCheckDebugProviderFactory() #else let providerFactory = YourAppCheckProviderFactory() #endif
Swift
#if targetEnvironment(simulator) let providerFactory = AppCheckDebugProviderFactory() #else let providerFactory = YourAppCheckProviderFactory() #endif
Objective-C
if (targetEnvironment == simulator){ FIRAppCheckDebugProviderFactory *providerFactory = [[FIRAppCheckDebugProviderFactory alloc] init]; [FIRAppCheck setAppCheckProviderFactory:providerFactory]; } else { YourAppCheckProviderFactory *providerFactory = [[YourAppCheckProviderFactory alloc] init]; [FIRAppCheck setAppCheckProviderFactory:providerFactory]; }
- 在 Xcode 项目中启用日志记录,启动应用,然后在日志中找到本地调试令牌。
- 将此令牌添加到 Firebase 控制台。
- 如需了解详情和相关说明,请参阅 App Check 文档。
如需在 CI 环境中运行应用,请执行以下操作:
- 在 Firebase 控制台中创建调试令牌,并将其添加到 CI 系统的安全密钥库中。
- 在 Xcode 中,向测试方案添加一个环境变量,其名称为
FIRAAppCheckDebugToken
,其值为$(APP_CHECK_DEBUG_TOKEN)
(或类似值)。 - 在 CI 测试脚本中,将调试令牌作为环境变量传递
创建并设置 App Check 调试提供方工厂。
此代码示例同时处理调试和生产场景:Places Swift SDK for iOS
#if DEBUG let providerFactory = AppCheckDebugProviderFactory() #else let providerFactory = YourAppCheckProviderFactory() #endif AppCheck.setAppCheckProviderFactory(providerFactory)
Swift
#if DEBUG let providerFactory = AppCheckDebugProviderFactory() #else let providerFactory = YourAppCheckProviderFactory() #endif AppCheck.setAppCheckProviderFactory(providerFactory)
Objective-C
#if DEBUG id<FIRAppCheckProviderFactory> providerFactory = [[FIRAppCheckDebugProviderFactory alloc] init]; #else // DEBUG id<FIRAppCheckProviderFactory> providerFactory = [[YourAppCheckProviderFactory alloc] init]; #endif // DEBUG AppCheck.setAppCheckProviderFactory(providerFactory)
- 如需了解详情和相关说明,请参阅 App Check 文档。
第 6 步:监控应用请求并决定强制执行措施
在开始强制执行之前,您需要确保不会干扰应用的合法用户。为此,请访问 App Check 指标界面,查看应用的流量中有多少百分比是经过验证的、过时的或非法的。当您发现大部分流量都已通过验证后,即可启用强制执行。
如需了解详情和相关说明,请参阅 Firebase App Check 文档。