Firebase App Check(Apple 平台)

1. 简介

Firebase App Check 可以确保来自合法的应用和设备,有助于保护您的后端资源免遭滥用(例如账单欺诈和钓鱼式攻击)。它可与 Firebase 服务和您自己的后端服务搭配使用,以确保您的资源安全无虞。

如需详细了解 Firebase App Check,请参阅 Firebase 文档。

App Check 使用平台专用服务来验证应用和/或设备的完整性。这些服务称为“证明提供程序”。其中一种提供方是 Apple 的 App Attest 服务,App Check 可以使用该服务来验证 Apple 应用和设备的真实性。

构建内容

在此 Codelab 中,您将在一个现有的示例应用中添加并强制执行 App Check,以保护项目的 Realtime Database 免遭非法应用和设备访问。

学习内容

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

所需条件

  • Xcode 13.3.1 或更高版本
  • 可让您创建新的应用标识符的 Apple 开发者账号
  • 支持 App Attest 的 iOS/iPadOS 设备(了解 App Attest API 可用性

2. 获取入门级项目

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

从命令行克隆适用于 iOS 的 Firebase 快速入门代码库

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

在 Xcode 中打开 Realtime Database SwiftUI 快速入门应用项目:

cd database/DatabaseExampleSwiftUI/DatabaseExample
xed .

3. 将 App Check 添加到您的应用

  1. 等待 Swift Package Manager 解析项目的依赖项。
  2. 打开 DatabaseExample (iOS) 应用目标的 General 标签页。然后,在 Frameworks, Libraries, and Embedded Content 部分中,点击 + 按钮。
  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 Authentication。
  • 初始化要保护的 Realtime Database 实例。
  • 配置 App Check。

创建项目

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

  1. Firebase 控制台中,选择添加项目
  2. 将项目命名为 App Check Codelab
  3. 点击继续
  4. 为此项目停用 Google Analytics(分析),然后点击创建项目

创建 Realtime Database 实例

现在,转到 Firebase 控制台的 Realtime Database 部分。

  1. 点击创建数据库按钮,启动数据库创建工作流。
  2. 保持数据库的默认位置 (us-central1) 不变,然后点击 Next
  3. 确保选择锁定模式,然后点击启用按钮,为您的数据库启用安全规则。
  4. 转到 Realtime Database 浏览器的规则标签页,并将默认规则替换为以下内容:
    {
        "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(项目概览)屏幕中,点击 + 添加应用按钮,然后点击 iOS+ 图标,将新的 iOS 应用添加到您的 Firebase 项目中。
  2. 输入应用的软件包 ID(使用您在上一部分中定义的 ID,例如 com.acme.samples.firebase.quickstart.DatabaseExample;请注意,此 ID必须是唯一标识符)
  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 Authentication

大功告成!到目前为止,设置已经有点麻烦了,但请耐心等候一下!如果您刚开始接触 Firebase,已经看到了工作流的基本组成部分,很快就会熟悉它们。

现在,您将为此应用配置 Firebase Authentication。

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

  1. 仍然在 Firebase 控制台中,打开控制台的 Authentication 部分。
  2. 点击开始使用,为您的项目设置 Firebase Authentication。
  3. 选择登录方法标签页。
  4. 原生提供方部分中选择电子邮件地址/密码
  5. 启用电子邮件地址/密码,然后点击保存

添加测试用户

  1. 打开 Authentication 部分的 Users 标签页。
  2. 点击添加用户
  3. 为测试用户指定电子邮件地址和密码,然后点击添加用户

试用应用

返回 Xcode,并在 iOS 模拟器上运行应用。使用您刚刚创建的测试用户的电子邮件地址和密码登录。登录后,你可以创建信息、对现有信息发表评论,以及为信息加星标/移除星标。

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

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

  1. 在 Firebase 控制台中,前往控制台的 App Check 部分。
  2. 点击开始使用
  3. 应用标签页中,点击您的应用以展开其详细信息。
  4. 点击 App Attest 配置 App Attest,然后输入 Apple Developer 帐号的团队 ID(您可以在 Apple Developer 门户的 Membership 部分找到该 ID):1645f7a369b678c2
  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. 打开您的应用目标设置中的 Signing & Capabilities 标签页
  3. 点击“+”按钮
  4. 在对话框中,找到并选择 App Attest 功能 ae84cd988a5fab31
  5. 执行上一步后,文件 DatabaseExample (iOS).entitlements 将显示在 Xcode 项目的根文件夹中。
  6. DatabaseExample (iOS).entitlements 文件中,将 App Attest Environment 键的值更改为 production.

您完成上述步骤并在 iOS 实体设备 (iPhone/iPad) 上启动应用后,该应用仍然可以访问 Realtime Database。在稍后的步骤中,您将强制执行 App Check,这会阻止从非法应用和设备发送请求。

如需详细了解此工作流,请参阅在 iOS 上使用 App Attest 启用 App Check

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

借助 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。例如,您可以使用其他证明提供程序(如 DeviceCheck),或者在 App Attest 不可用的操作系统版本上使用自定义证明提供程序。请参阅下面的示例:

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

注意:调试密钥会在应用首次启动时为模拟器生成,并存储在用户默认设置中。如果您移除应用、重置模拟器或使用其他模拟器,系统会生成新的调试密钥。请务必注册新的调试密钥。

注册调试密钥

  1. 返回 Firevbase 控制台,前往 App Check 部分。
  2. 应用标签页中,点击您的应用以展开其详细信息。
  3. 在溢出菜单中,选择管理调试令牌d77c8ff768a00b4b
  4. 添加您从 Xcode 控制台复制的 Secret,然后点击 Save (保存)f845c97b86f694d0.png

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

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

如需详细了解此流程,请参阅相关文档 - 请参阅在 iOS 上将 App Check 与调试提供程序搭配使用

9. 为 Firebase Realtime Database 启用 App Check 强制执行

目前,我们的应用声明了一个 AppCheckProviderFactory,它会针对真实设备返回 AppAttestProvider。在实体设备上运行时,您的应用将执行证明并将结果发送到 Firebase 后端。不过,Firebase 后端仍会接受来自任何设备、iOS 模拟器、脚本等的请求。如果您仍有用户使用旧版应用且未使用 App Check 的用户,并且您还不想强制执行访问权限检查,则此模式非常有用。

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

  1. 在 Firebase 控制台的 App Check 部分中,点击 Realtime Database 以展开其详细信息。
  2. 点击强制执行

64e6a81fa979b635

  1. 阅读确认对话框中的信息,然后点击强制执行

完成这些步骤后,只有合法应用才能访问该数据库。所有其他应用都会被屏蔽。

尝试使用非法应用访问 Realtime Database

如需查看 App Check 强制执行情况,请按以下步骤操作:

  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.
    

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

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

10. 恭喜!

9785d32f18b995d2.gif

现在您已了解如何:

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

后续步骤

学习“使用 Firebase Remote Config 逐步部署 Firebase App Check”Codelab,了解如何使用 Remote Config 逐步向用户部署 App Check

下面列出了可能对您有帮助的其他资源

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