适用于 Apple 平台的 Firebase 应用检查

一、简介

Firebase App Check 确保请求来自合法的应用和设备,从而帮助保护您的后端资源免遭滥用,例如计费欺诈和网络钓鱼。它适用于 Firebase 服务和您自己的后端服务,以确保您的资源安全。

您可以在 Firebase 文档中了解有关Firebase 应用检查的更多信息。

App Check 使用特定于平台的服务来验证应用程序和/或设备的完整性。这些服务称为证明提供者。此类提供商之一是 Apple 的App Attest服务,App Check 可以使用该服务来验证 Apple 应用程序和设备的真实性。

您将构建什么

在此 Codelab 中,您将在现有示例应用程序中添加并强制执行 App Check,以保护项目的实时数据库免受非法应用程序和设备的访问。

你会学到什么

  • 如何将 Firebase 应用检查添加到现有应用。
  • 如何安装不同的 Firebase App Check 证明提供程序。
  • 如何为您的应用配置 App Attest。
  • 如何配置调试证明提供程序以在应用程序开发期间在模拟器上测试您的应用程序。

你需要什么

  • Xcode 13.3.1 或更高版本
  • 一个 Apple Developer 帐户,可让您创建新的应用标识符
  • 支持 App Attest 的 iOS/iPadOS 设备(了解App Attest API 可用性

2. 获取启动项目

适用于 iOS 的 Firebase 快速入门存储库包含用于演示不同 Firebase 产品的示例应用。您将使用适用于 SwiftUI 的 Firebase 数据库快速入门应用作为此 Codelab 的基础。

从命令行克隆Firebase Quickstarts for iOS 存储库

git clone https://github.com/firebase/quickstart-ios.git
cd quickstart-ios

在 Xcode 中打开实时数据库 SwiftUI 快速入门应用项目:

cd database/DatabaseExampleSwiftUI/DatabaseExample
xed .

3. 将应用检查添加到您的应用

  1. 等待 Swift Package Manager 解决项目的依赖关系。
  2. 打开DatabaseExample (iOS)应用程序目标的常规选项卡。然后,在框架、库和嵌入式内容部分中,单击+按钮。
  3. 选择添加FirebaseAppCheck

4. 创建并安装 App Check 提供者工厂

  1. Shared文件组中,添加一个名为AppCheck的新组。
  2. 在该组中,在单独的文件中创建一个工厂类,例如MyAppCheckProviderFactory.swift ,确保将其添加到DatabaseExample (iOS)目标:
    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.
          return AppCheckDebugProvider(app: app)
        #else
          // Use App Attest provider on real devices.
          return AppAttestProvider(app: app)
        #endif
      }
    }
    
  3. 接下来,在DatabaseExampleApp.swift中,确保导入FirebaseAppCheck ,并将MyAppCheckProviderFactory类的实例设置为 App Check 提供程序工厂。
    import SwiftUI
    import FirebaseCore
    import FirebaseAppCheck
    
    @main
    struct DatabaseExampleApp: App {
      init() {
        // Set an instance of MyAppCheckProviderFactory as an App Check
        // provider factory before configuring Firebase.
        AppCheck.setAppCheckProviderFactory(MyAppCheckProviderFactory())
        FirebaseApp.configure()
      }
      ...
    }
    

5. 创建和配置 Firebase 项目

要在您的 iOS 项目中使用 App Check,您需要在 Firebase 控制台中执行以下步骤:

  • 设置 Firebase 项目。
  • 将您的 iOS 应用添加到 Firebase 项目。
  • 配置 Firebase 身份验证。
  • 初始化您要保护的实时数据库实例。
  • 配置应用检查。

创建项目

首先,您需要创建一个 Firebase 项目。

  1. Firebase 控制台中,选择添加项目
  2. 将您的项目命名App Check Codelab
  3. 单击继续。
  4. 为此项目禁用 Google Analytics,然后单击创建项目。

创建实时数据库实例

现在,导航到 Firebase 控制台的实时数据库部分。

  1. 单击创建数据库按钮以启动数据库创建工作流程。
  2. 保持数据库的默认位置 ( us-central1 ) 不变,然后单击Next
  3. 确保选择了锁定模式并单击启用按钮为您的数据库启用安全规则。
  4. 导航到实时数据库浏览器的规则选项卡,并将默认规则替换为以下内容:
    {
        "rules": {
            // User profiles are only readable/writable by the user who owns it
            "users": {
                "$UID": {
                    ".read": "auth.uid == $UID",
                    ".write": "auth.uid == $UID"
                }
            },
            // Posts can be read by anyone but only written by logged-in users.
            "posts": {
                ".read": true,
                ".write": "auth.uid != null",
                "$POSTID": {
                    // UID must match logged in user and is fixed once set
                    "uid": {
                        ".validate": "(data.exists() && data.val() == newData.val()) || newData.val() == auth.uid"
                    },
                    // User can only update own stars
                    "stars": {
                        "$UID": {
                            ".validate": "auth.uid == $UID"
                        }
                    }
                }
            },
            // User posts can be read by anyone but only written by the user that owns it,
            // and with a matching UID
            "user-posts": {
                ".read": true,
                "$UID": {
                    "$POSTID": {
                        ".write": "auth.uid == $UID",
                        ".validate": "data.exists() || newData.child('uid').val() == auth.uid"
                    }
                }
            },
            // Comments can be read by anyone but only written by a logged in user
            "post-comments": {
                ".read": true,
                ".write": "auth.uid != null",
                "$POSTID": {
                    "$COMMENTID": {
                        // UID must match logged in user and is fixed once set
                        "uid": {
                            ".validate": "(data.exists() && data.val() == newData.val()) || newData.val() == auth.uid"
                        }
                    }
                }
            }
        }
    }
    
  5. 单击发布按钮以激活更新的安全规则。

准备您的 iOS 应用以连接到 Firebase

为了能够在物理设备上运行示例应用程序,您需要将项目添加到您的开发团队,以便 Xcode 可以为您管理所需的配置文件。按照以下步骤将示例应用添加到您的开发者帐户:

  1. 在 Xcode 中,在项目导航器中选择DatabaseExample项目。
  2. 选择DatabaseExample (iOS)目标并打开Signing & Capabilities选项卡。
  3. 您应该会看到一条错误消息,指出“Signing for DatabaseExample (iOS) requires a development team”
  4. 包标识符更新为唯一标识符。实现此目的的最简单方法是使用您网站的反向域名,例如com.acme.samples.firebase.quickstart.DatabaseExample (请不要使用此 ID;请选择您自己的唯一 ID)。
  5. 选择您的开发团队。
  6. 当 Xcode 显示“Provisioning Profile: Xcode Managed Profile”和这个标签旁边的一个小信息图标时,你就会知道一切都很顺利。单击此图标将显示有关配置文件的更多详细信息。

连接您的 iOS 应用程序

有关连接您的应用程序的深入说明,请查看有关将 Firebase 添加到您的 iOS 项目的文档。要开始使用,请在 Firebase 控制台中执行以下主要步骤:

  1. 在新项目的Project Overview屏幕中,单击+ Add app按钮,然后单击iOS+图标以将新的 iOS 应用添加到您的 Firebase 项目。
  2. 输入您的应用程序的捆绑包 ID(使用您在上一节中定义的 ID,例如com.acme.samples.firebase.quickstart.DatabaseExample - 请记住,这必须是唯一标识符)
  3. 单击注册应用程序
  4. Firebase 会生成一个GoogleService-Info.plist文件,其中包含您的应用所需的所有 Firebase 元数据。
  5. 单击下载 GoogleService-Info.plist以下载文件。
  6. 在 Xcode 中,您将看到该项目已经包含一个名为GoogleService-Info.plist的文件。首先删除此文件 - 您将在下一步中将其替换为您自己的 Firebase 项目的文件。
  7. 将您在上一步中下载的GoogleService-Info.plist文件复制到 Xcode 项目的根文件夹中,并将其添加到DatabaseExample (iOS)目标中,确保将其命名为GoogleService-Info.plist
  8. 单击注册流程的其余步骤。由于示例项目已正确设置,因此您无需对代码进行任何更改。

配置 Firebase 身份验证

呸!到目前为止,这是相当多的设置,但请坚持!如果您是 Firebase 的新手,那么您已经了解了很快就会熟悉的工作流程的重要部分。

现在,您将为该应用配置 Firebase 身份验证。

启用身份验证电子邮件/密码登录提供程序

  1. 仍在Firebase 控制台中,打开控制台的Authentication部分。
  2. 单击开始为您的项目设置 Firebase 身份验证。
  3. 选择登录方法选项卡。
  4. 在本机提供程序部分中选择电子邮件/密码
  5. 启用电子邮件/密码,然后单击保存

添加测试用户

  1. 打开身份验证部分的用户选项卡。
  2. 单击添加用户
  3. 为您的测试用户指定电子邮件和密码,然后单击Add user

试一试该应用程序

返回 Xcode,在 iOS 模拟器上运行应用程序。使用您刚刚创建的测试用户的电子邮件和密码登录。登录后,创建帖子、对现有帖子发表评论以及为帖子加星/取消星标。

6. 配置 App Attest 证明提供者

在此步骤中,您将配置 App Check 以在 Firebase 控制台中使用 App Attest 提供程序。

  1. 在 Firebase 控制台中,导航到控制台的App Check部分。
  2. 单击开始
  3. 应用程序选项卡中,单击您的应用程序以展开其详细信息。
  4. 单击App Attest配置 App Attest,然后输入您的 Apple Developer Account 的 Team ID(您可以在 Apple Developer 门户的Membership部分找到它): 1645f7a369b678c2.png
  5. 单击保存

这样,您就有了一个连接到我们的新应用的有效 Firebase 项目,并且启用了 App Check。

您现在已准备好配置我们的特定证明服务!有关此工作流程的更多信息,请参阅在 iOS 上使用 App Attest 启用 App Check

7. 为您的应用程序配置 App Attest

现在是时候开始使用 Firebase App Check SDK 并实现一些客户端代码了。

首先,您需要配置 Xcode 项目,以便 SDK 可以使用 Apple 的 App Attest API 来确保从您的应用发送的请求来自您应用的合法实例。

  1. 在 Xcode 项目中为您的应用目标添加 App Attest 功能:
  2. 在您的应用目标设置中打开“签名和功能”选项卡
  3. 点击“ + ”按钮
  4. 在对话框中,找到并选择App Attest能力ae84cd988a5fab31.png
  5. 执行上一步后,文件DatabaseExample (iOS).entitlements将出现在 Xcode 项目的根文件夹中。
  6. DatabaseExample (iOS).entitlements文件中,将App Attest Environment键的值更改为production.

完成这些步骤并在物理iOS 设备 (iPhone/iPad) 上启动应用程序后,该应用程序仍将能够访问实时数据库。在稍后的步骤中,您将强制执行App Check,这将阻止来自非法应用程序和设备的请求。

要了解有关此工作流程的更多信息,请参阅在 iOS 上使用 App Attest 启用 App Check

8. 为 iOS 模拟器配置一个 Debug Attestation Provider

Firebase App Check Debug提供程序可以在开发过程中在不受信任的环境(包括 iOS 模拟器)中使用 Firebase App Check 强制测试应用程序。接下来,您需要一起配置调试提供程序。

在您的应用中安装 Firebase 调试提供程序

选项 1:有条件地在您的工厂中创建调试提供程序的实例

您在创建 App Check 提供程序工厂时完成了大部分工作。在此步骤中,您将添加调试提供程序生成的本地调试密钥的日志记录,以便您可以在 Firebase 控制台中注册此应用实例以进行调试。

使用以下代码更新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
    // Use App Attest provider on real devices.
    return AppAttestProvider(app: app)
#endif
  }
}

这种方法使我们可以更灵活地根据环境配置 App Check。例如,您可以在App Attest不可用的操作系统版本上使用其他证明提供程序(如DeviceCheck)或自定义证明提供程序。请参见下面的示例:

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 App Attest provider on real devices.
        return AppAttestProvider(app: app)
      } else {
        return DeviceCheckProvider(app: app)
      }
      #endif
  }
}

选项 2:安装AppCheckDebugProviderFactory

对于更简单的情况,您可以在配置 Firebase 应用程序实例之前临时或有条件地安装AppCheckDebugProviderFactory

init() {
#if targetEnvironment(simulator)
  let providerFactory = AppCheckDebugProviderFactory()
#else
  let providerFactory = MyAppCheckProviderFactory()
#endif

  AppCheck.setAppCheckProviderFactory(providerFactory)

  FirebaseApp.configure()
}

这将为您节省几行代码来创建您自己的 App Check 提供程序工厂。

在 Firebase 控制台中注册您的调试密钥

从您的 iOS 模拟器获取调试密码

  1. 如果您选择安装AppCheckDebugProviderFactory (上面的选项 2),则需要通过将-FIRDebugEnabled添加到应用启动参数来为您的应用启用调试日志记录: f1c6b477a373e144.png
  2. 在模拟器上运行您的应用
  3. 在 Xcode 控制台中找到调试密码。您可以使用控制台过滤器更快地找到它: d4c65af93e369c55.png

注意:调试密码是在第一次启动应用程序时为您的模拟器生成的,并存储在用户默认值中。如果您删除应用程序、重置模拟器或使用另一个模拟器,将生成一个新的调试密码。确保注册新的调试密码。

注册调试密码

  1. 返回 Firevbase 控制台,转到App Check部分。
  2. 应用程序选项卡中,单击您的应用程序以展开其详细信息。
  3. 在溢出菜单中,选择Manage debug tokensd77c8ff768a00b4b.png
  4. 添加您从 Xcode 控制台复制的密钥,然后单击保存f845c97b86f694d0.png

完成这些步骤后,即使强制执行 App Check,您也可以在模拟器上使用该应用程序。

注意:调试提供程序专门设计用于帮助防止调试机密泄漏。使用当前方法,您无需将调试密码存储在源代码中。

有关此流程的更多详细信息,请参阅文档 - 请参阅在 iOS 上通过调试提供程序使用 App Check

9. 为 Firebase 实时数据库启用应用检查强制

目前,我们的应用程序声明了一个AppCheckProviderFactory ,它为真实设备返回一个AppAttestProvider 。在物理设备上运行时,您的应用将执行证明并将结果发送到 Firebase 后端。但是,Firebase 后端仍然接受来自任何设备、iOS 模拟器、脚本等的请求。当您仍然有用户使用旧版本的应用但没有应用检查,并且您不想强制访问时,此模式很有用检查呢。

现在,您需要启用应用检查强制以确保 Firebase 应用只能从合法设备访问。为 Firebase 项目启用强制执行后,未集成 App Check 的旧应用版本将停止工作。

  1. App Check部分的 Firebase 控制台中,单击实时数据库以展开其详细信息。
  2. 单击强制执行

64e6a81fa979b635.png

  1. 阅读确认对话框中的信息,然后单击Enforce

完成这些步骤后,只有合法的应用程序才能访问数据库。所有其他应用程序将被阻止。

尝试使用非法应用访问实时数据库

要查看应用检查实施的实际效果,请执行以下步骤:

  1. 通过在DatabaseExampleApp中应用程序入口点的init方法中注释掉 App Check 注册代码来关闭 App Check 注册。
  2. 通过选择Device > Erase All Content and Settings重置模拟器。这将擦除模拟器(并使设备令牌无效)。
  3. 在模拟器上再次运行应用程序。
  4. 您现在应该看到以下错误消息:
    [FirebaseDatabase][I-RDB034005] Firebase Database connection was forcefully killed by the server.  Will not attempt reconnect. Reason: Invalid appcheck token.
    

要重新启用 App Check,请执行以下操作:

  1. DatabaseExampleApp中取消注释 App Check 注册码。
  2. 重新启动应用程序。
  3. 记下 Xcode 控制台中的新 App Check 令牌。
  4. 在 Firebase 控制台的应用检查设置中注册调试令牌。
  5. 重新运行应用程序。
  6. 您应该不会再看到错误消息,并且应该能够在应用程序中添加新帖子和评论。

10. 恭喜!

9785d32f18b995d2.gif

现在您知道如何:

  • 将 App Check 添加到现有项目
  • 为您的应用的生产版本配置应用证明证明提供程序
  • 配置调试证明提供程序以在模拟器上测试您的应用
  • 观察应用版本发布,了解何时为您的 Firebase 项目实施应用检查
  • 启用应用检查强制

下一步

使用 Firebase 远程配置代码实验室逐步推出 Firebase 应用检查中了解如何使用远程配置逐步向您的用户推出应用检查

这些是您可能会发现有用的其他资源

此 codelab 中描述的设置适用于大多数情况,但 App Check 可在需要时为您提供更大的灵活性 - 请查看以下链接以获取更多详细信息: