返回

解决iOS Firebase AppCheck Google认证错误:Access Blocked

IOS

Firebase AppCheck:保护 iOS 应用中的 Google 身份验证

在使用 Firebase 构建跨平台应用时,我们往往会关注如何为 Android 和 iOS 平台都提供安全的用户认证。当 Firebase Authentication 与 AppCheck 结合使用时,可以有效防止来自未知或伪造客户端的访问请求。通常,这在 Android 上顺利运行。然而,当为 iOS 应用启用 "Google Identity for iOS" 的强制执行时,开发者可能会遇到 "Access Blocked: Authorization Error" 以及 "Error 400: invalid_request" 的问题,同时在 Firebase 控制台中显示 "Unverified: Outdated Client Requests" 的错误信息。这种状况看似与 AppCheck 在 Android 上的行为存在差异,让人费解。本文探讨这类问题的成因并提供相应的解决方案。

问题剖析:AppCheck 与 Google 身份验证

表面上看,Firebase Authentication 的 AppCheck 功能理应涵盖所有认证请求,包括 Google 身份验证。在 Android 上,事实的确如此。一旦对 Firebase Authentication 强制执行 AppCheck,只有经过验证的应用客户端才被允许执行认证操作,而未经过验证的请求将会被阻止。可是,当 iOS 应用尝试使用 Google 账号登录,同时 "Google Identity for iOS" 的 AppCheck 执行被启用时,便会引发意想不到的问题。这通常表明 iOS 平台处理 Google 身份验证的方式与 Android 不同,需要额外的配置。

解决方案一:更新 Google 身份验证 SDK

旧版本的 Google 身份验证 SDK 可能会存在一些与 AppCheck 的兼容问题,特别是在处理 AppCheck 令牌时。确保你的 iOS 项目正在使用最新版本的 Google 身份验证 SDK,可以避免一些因版本不兼容导致的错误。

操作步骤:

  1. 使用 CocoaPods 或者 Swift Package Manager 更新 GoogleSignIn 或其他相关的 SDK:
# 使用 CocoaPods
pod update GoogleSignIn

// 使用 Swift Package Manager, 更新 Package
File -> Add Package Dependencies,搜索 https://github.com/google/GoogleSignIn-iOS, 更新 Package
  1. 清理 Xcode 工程(Product -> Clean Build Folder),重新构建并运行。

更新依赖包并不会立即修复所有问题。这只是个排查问题的起点。它保证使用了兼容性更好的代码版本。

解决方案二:检查 GoogleService-Info.plist 文件配置

不正确的配置可能会导致认证过程失败。仔细检查你添加到 Xcode 工程的 GoogleService-Info.plist 文件,保证里面的信息与你在 Firebase 项目的设置一致。重点检查以下内容:

  • CLIENT_ID:确保 Google 身份验证的客户端 ID 正确。
  • REVERSED_CLIENT_ID:确认这个值已在项目设置中正确配置。

操作步骤:

  1. 下载最新的 GoogleService-Info.plist 文件,路径为你的 Firebase 项目 -> 项目设置 -> 通用 -> 你的 iOS 应用卡片。
  2. 替换 Xcode 工程中的旧版本,请不要仅仅删除重新导入。
  3. 再次清理 Xcode 工程并运行。

确保 GoogleService-Info.plist 的配置完全匹配项目配置,这是基础而关键的一步。

解决方案三:检查和修正 AppDelegate.swift 中的配置

尽管基本设置已存在于 AppDelegate.swift 文件中,它仍然需要被验证,它保证 Flutter 引擎启动的时候能够初始化 Firebase App,这为 AppCheck 工作提供前提条件。

操作步骤:

  1. AppDelegate.swift 确认以下的代码:
 import UIKit
 import Flutter
 import FirebaseCore

 @UIApplicationMain
 @objc class AppDelegate: FlutterAppDelegate {
     override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {

          FirebaseApp.configure() // 务必加上
        GeneratedPluginRegistrant.register(with: self)
      return super.application(application, didFinishLaunchingWithOptions: launchOptions)
   }
}
  1. 如果发现 FirebaseApp.configure() 没有加入到 AppDelegate.swift, 需要添加它,并且需要运行 flutter clean && flutter pub get 后重新 build 并运行程序,如果使用了 cocoa pods, 可能需要更新 cocoa pods 依赖。

在一些情况下,AppDelegate.swift 可能没有调用 FirebaseApp.configure() 。 如果出现问题,验证初始化配置能够修复 "Unverified: Outdated Client Requests" 问题。

解决方案四:AppCheck 设备验证

如果前述方法不能解决问题,需要仔细考虑 iOS AppCheck 对开发/调试模式与生产模式的要求。对于测试和调试阶段,您应该正确注册您的设备,或通过使用调试令牌来绕过 AppCheck 的限制。在发布到 App Store 前,需要清除这些测试配置, 并完全依赖正式的 AppCheck 执行。

操作步骤:

  1. 在 Firebase 控制台找到 App Check 部分, 添加模拟器的 debug token ( 步骤请参考 Firebase AppCheck 官方文档)。
  2. 确保 Xcode 启动项目使用的 Scheme 是 Release模式时,调试令牌不会生效。这可以在 scheme 的 build 配置里面找到.
  3. 清理 Xcode 工程,重新构建。

额外的安全建议

  • 定期更新依赖项: 定期更新 Firebase SDK 和相关依赖,能避免许多已知漏洞。
  • 监控 AppCheck 活动: 密切监视 Firebase 控制台中的 AppCheck 活动,并定期查看是否有异常请求或不必要的拒绝。
  • 安全发布: 注意区分 debug mode 与 release mode 的配置。 debug 模式下的 AppCheck 是放松的安全机制,release 下则要保证更加严苛。
  • 代码签名: 正确配置和管理 iOS 应用的代码签名证书,这是验证应用来源和防止中间人攻击的重要环节。

总结

当在 iOS 中为 Google 身份验证强制执行 AppCheck 时,可能会出现意料之外的挑战。通过排查 Google 身份验证 SDK 版本,核查 GoogleService-Info.plist 的配置、确保 Firebase 应用初始化配置的正确,以及理解 AppCheck 的设备验证机制,大部分问题都能有效解决。在实际部署过程中,除了 AppCheck 配置,还需要将代码安全作为日常工作流程的一部分。