为 Cloud Functions 启用 App Check 强制执行

了解 App Check 对用户有何影响并为后续操作做好准备之后,您便可以启用 App Check 强制执行。

启用强制执行

如需开始在 Callable Cloud Functions 中强制执行 App Check 令牌要求,请修改函数以检查是否具有有效的 App Check 令牌,如下所示。启用强制执行后,所有未经验证的请求都将被拒绝。

  1. 安装 Cloud Functions SDK。

    Node.js(第 1 代)

    将项目的 firebase-functions 依赖项更新为 4.0.0 或更高版本:

    npm install firebase-functions@">=4.0.0"

    Node.js(第 2 代)

    将项目的 firebase-functions 依赖项更新为 4.0.0 或更高版本:

    npm install firebase-functions@">=4.0.0"

    Python(预览版)

    firebase-functions 添加到 functions/requirements.txt

    firebase-functions >= 0.1.0
    

    然后,更新您项目的虚拟环境中的依赖项:

    ./venv/bin/pip install -r requirements.txt
    
  2. 为您的函数启用 App Check 强制执行运行时选项:

    Node.js(第 1 代)

    const functions = require("firebase-functions/v1");
    
    exports.yourV1CallableFunction = functions
      .runWith({
          enforceAppCheck: true, // Reject requests with missing or invalid App Check tokens.
      })
      .https.onCall((data, context) => {
            // context.app contains data from App Check, including the app ID.
            // Your function logic follows.
            ...
      });
    

    Node.js(第 2 代)

    const { onCall } = require("firebase-functions/v2/https");
    
    exports.yourV2CallableFunction = onCall(
      {
        enforceAppCheck: true, // Reject requests with missing or invalid App Check tokens.
      },
      (request) => {
        // request.app contains data from App Check, including the app ID.
        // Your function logic follows.
        ...
      }
    );
    

    Python(预览版)

    from firebase_functions import https_fn
    
    @https_fn.on_call(
        enforce_app_check=True  # Reject requests with missing or invalid App Check tokens.
    )
    def your_callable_function(req: https_fn.CallableRequest) -> https_fn.Response:
        # req.app contains data from App Check, including the app ID.
        # Your function logic follows.
        ...
    
  3. 重新部署您的函数:

    firebase deploy --only functions
    

部署这些更改后,Callable Cloud Functions 将需要有效的 App Check 令牌。当您调用 Callable 函数时,Cloud Functions 客户端 SDK 会自动附加 App Check 令牌。

重放攻击防范(Beta 版)

为保护 Callable 函数免遭重放攻击,您可以在验证 App Check 令牌后消耗掉该令牌。令牌一经消耗便无法再次使用。

请注意,使用重放攻击防范会增加令牌验证的网络往返时间,因此 Cloud Functions 函数调用的延迟时间会增加。因此,大多数应用通常仅在特别敏感的端点上启用重放攻击防范。

如需消耗掉令牌,请执行以下操作:

  1. Cloud 控制台中,将“Firebase App Check Token Verifier”角色授予 Cloud Functions 函数使用的服务账号。

    • 如果您明确初始化 Admin SDK 并且指定了项目的 Admin SDK 服务账号凭据,则此必要的角色已授予。
    • 如果您将第 1 代 Cloud Functions 函数与默认的 Admin SDK 配置搭配使用,请将该角色授予 App Engine 默认服务账号。请参阅更改服务账号权限
    • 如果您将第 2 代 Cloud Functions 函数与默认的 Admin SDK 配置搭配使用,请将该角色授予默认计算服务账号
  2. 在函数定义中将 consumeAppCheckToken 设置为 true

    Node.js(第 1 代)

    const functions = require("firebase-functions/v1");
    
    exports.yourV1CallableFunction = functions
      .runWith({
          enforceAppCheck: true, // Reject requests with missing or invalid App Check tokens.
          consumeAppCheckToken: true  // Consume the token after verification.
      })
      .https.onCall((data, context) => {
          // context.app contains data from App Check, including the app ID.
          // Your function logic follows.
          ...
      });
    

    Node.js(第 2 代)

    const { onCall } = require("firebase-functions/v2/https");
    
    exports.yourV2CallableFunction = onCall(
      {
        enforceAppCheck: true, // Reject requests with missing or invalid App Check tokens.
        consumeAppCheckToken: true  // Consume the token after verification.
      },
      (request) => {
        // request.app contains data from App Check, including the app ID.
        // Your function logic follows.
        ...
      }
    );
    
  3. 更新应用客户端代码,以便在调用函数时获取可消耗的限制使用令牌:

    Swift

    let options = HTTPSCallableOptions(requireLimitedUseAppCheckTokens: true)
    let yourCallableFunction =
        Functions.functions().httpsCallable("yourCallableFunction", options: options)
    do {
        let result = try await yourCallableFunction.call()
    } catch {
        // ...
    }
    

    Web

    import { getFunctions, httpsCallable } from "firebase/functions";
    
    const yourCallableFunction = httpsCallable(
      getFunctions(),
      "yourCallableFunction",
      { limitedUseAppCheckTokens: true },
    );
    await yourCallableFunction();
    

    Kotlin+KTX

    val yourCallableFunction = Firebase.functions.getHttpsCallable("yourCallableFunction") {
        limitedUseAppCheckTokens = true
    }
    val result = yourCallableFunction.call().await()
    

    Java

    HttpsCallableReference yourCallableFunction = FirebaseFunctions.getInstance().getHttpsCallable(
            "yourCallableFunction",
            new HttpsCallableOptions.Builder()
                    .setLimitedUseAppCheckTokens(true)
                    .build()
    );
    Task<HttpsCallableResult> result = yourCallableFunction.call();