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

一、简介

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

您可以在 Firebase 文档中了解有关Firebase App Check的更多信息。

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

你将构建什么

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

你将学到什么

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

你需要什么

  • Xcode 13.3.1 或更高版本
  • 允许您创建新应用程序标识符的 Apple 开发者帐户
  • 支持 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)目标并打开“签名和功能”选项卡。
  3. 您应该会看到一条错误消息,指出“Signing for DatabaseExample (iOS)需要开发团队”
  4. 包标识符更新为唯一标识符。实现此目的的最简单方法是使用网站的反向域名,例如com.acme.samples.firebase.quickstart.DatabaseExample (请不要使用此 ID;请选择您自己的唯一 ID)。
  5. 选择您的开发团队。
  6. 当 Xcode 显示“Provisioning Profile: Xcode Managed Profile”以及该标签旁边的小信息图标时,您就会知道一切进展顺利。单击此图标将显示有关配置文件的更多详细信息。

连接您的 iOS 应用程序

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

  1. 在新项目的“项目概述”屏幕中,单击+ 添加应用程序按钮,然后单击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 控制台中,打开控制台的“身份验证”部分。
  2. 单击开始为您的项目设置 Firebase 身份验证。
  3. 选择登录方法选项卡。
  4. 本机提供商部分中选择电子邮件/密码
  5. 启用电子邮件/密码并单击保存

添加测试用户

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

试用一下该应用程序

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

6. 配置 App Attest 证明提供程序

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

  1. 在 Firebase 控制台中,导航到控制台的“应用检查”部分。
  2. 单击开始
  3. “应用程序”选项卡中,单击您的应用程序以展开其详细信息。
  4. 单击“App Attest”以配置“App Attest”,然后输入您的 Apple 开发者帐户的团队 ID(您可以在 Apple 开发者门户的“会员资格”部分找到此信息): 1645f7a369b678c2.png
  5. 单击“保存”

这样,您就有了一个连接到我们的新应用程序的工作 Firebase 项目,并且启用了应用程序检查。

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

7. 为您的应用程序配置应用程序证明

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

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

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

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

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

8. 为 iOS 模拟器配置调试证明提供程序

Firebase App Check 调试提供程序可以在开发过程中在不受信任的环境(包括 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 控制台,转到应用程序检查部分。
  2. “应用程序”选项卡中,单击您的应用程序以展开其详细信息。
  3. 在溢出菜单中,选择管理调试令牌d77c8ff768a00b4b.png
  4. 添加从 Xcode 控制台复制的密钥,然后单击“保存” f845c97b86f694d0.png

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

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

有关此流程的更多详细信息可以在文档中找到 - 请参阅在 iOS 上使用 App Check 与调试提供程序

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

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

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

  1. 在 Firebase 控制台的“应用检查”部分中,单击“实时数据库”以展开其详细信息。
  2. 单击“强制”

64e6a81fa979b635.png

  1. 阅读确认对话框中的信息,然后单击“强制”

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

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

要查看应用程序检查的实际执行情况,请按照以下步骤操作:

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

要重新启用应用程序检查,请执行以下操作:

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

10. 恭喜!

9785d32f18b995d2.gif

现在您知道如何:

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

下一步

在使用 Firebase Remote Config 逐步推出 Firebase App Check Codelab 中了解如何使用 Remote Config 逐步向用户推出App Check

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

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