为 Cloud Functions 启用 App Check 强制执行

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

启用强制执行

如需开始在可调用的 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
    

部署这些更改后,可调用的 Cloud Functions 函数将需要有效的 App Check 令牌。当您调用可调用的函数时,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();