首页 > 解决方案 > Firebase Functions AppCheck 不断让我的设备失败

问题描述

我一直在尝试将 AppCheck 与我的 Android 应用程序集成,但我似乎无法发出有效的请求。

至于测试目的,我一直在使用以下代码:

安卓代码

class Application : MultiDexApplication() {

    override fun onCreate() {
        FirebaseApp.initializeApp(this)

        val appCheck = FirebaseAppCheck.getInstance()
        if (BuildConfig.DEBUG) appCheck.installAppCheckProviderFactory(DebugAppCheckProviderFactory.getInstance(), true)
        else appCheck.installAppCheckProviderFactory(SafetyNetAppCheckProviderFactory.getInstance(), true)

        super.onCreate()
    }
}

class TestActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        val data = "This is a test!"
        Firebase.functions.getHttpsCallable("test").call(data).addOnCompleteListener {
            if (it.isSuccessful) {
                val result = it.result.data
                print(result)
            }

            else {
                val exception = it.exception
                print(exception)
            }
        }
    }
}

功能码

const functions = require("firebase-functions")

exports.test = functions.https.onCall((data, context) => {
  if (context.app == undefined) {
    functions.logger.error("Test - Failed validating device integrity!")
    throw new functions.https.HttpsError("failed-precondition", "The function must be called from an App Check verified app")
  }

  return data
})

我已将DebugAppCheckProviderFactory令牌添加到 Firebase 控制台,但无论我做什么,如果它是模拟器或物理设备,当我调用该函数时,总是会抛出失败的前置条件异常。

检查功能日志,我可以看到该应用程序丢失:

在此处输入图像描述

我已经多次阅读文档,并且似乎没有遗漏任何步骤。我是否遗漏了什么,或者我能做些什么来找到这个的根本原因?

感谢您的时间!

编辑:

至于 Martin 的建议,我创建了一个新的OnRequest函数并添加了X-Firebase-AppCheck标头。我正确收到了令牌,并且能够通过以下方式成功验证它:

firebaseAdmin.appCheck().verifyToken(appCheckToken)

所以,我的猜测是,Android 并没有像它应该的那样将X-Firebase-AppCheck自动添加到OnCall函数中。

我运行代码并通过代码设置了一些断点,并注意到以下内容。Firebase的调用方法是添加Firebase-Instance-ID-Token但我似乎无法在任何地方找到X-Firebase-AppCheck标头。也许我不应该看到这个值,或者我只是找不到它被添加的位置。或者它可能根本没有添加,因此我根本无法验证我的context.app

标签: androidfirebasegoogle-cloud-functionsfirebase-app-check

解决方案


可能需要获得AppCheckToken

FirebaseAppCheck
        .getInstance()
        .getAppCheckToken(false)
        .addOnSuccessListener(new OnSuccessListener<AppCheckToken>() {
            @Override
            public void onSuccess(@NonNull AppCheckToken tokenResponse) {

                String appCheckToken = tokenResponse.getToken();
                ...
            }
        });

必须与 HTTP 请求一起传递(示例显示 Retrofit,也可以使用它来代替HttpsCallable

@GET("yourExampleEndpoint")
Call<List<String>> exampleData(
    @Header("X-Firebase-AppCheck") String appCheckToken,
    ...
);

WhereFirebaseFunctions.getInstance().getHttpsCallable().call()没有说明如何或是否必须明确设置该X-Firebase-AppCheck标头。Cloud Functions 通常应该收到一个X-Firebase-AppCheck标头 - 带有之前检索到的 AppCheck 令牌:

const appCheckToken = req.header('X-Firebase-AppCheck');

if (!appCheckToken) {
    res.status(401);
    return next('Unauthorized');
}

try {
    const appCheckClaims = await firebaseAdmin.appCheck().verifyToken(appCheckToken);
    // If verifyToken() succeeds, continue with the next middleware function in the stack.
    return next();
} catch (err) {
    res.status(401);
    return next('Unauthorized');
}

也可以发行自己的令牌......并且检查context-app也是有效的。


更新:https.onCall 的协议规范如下:

可选:X-Firebase-AppCheck: <token>

发出请求的客户端应用提供的 Firebase 应用检查令牌。后端自动验证此令牌并对其进行解码,将 appId 注入处理程序的上下文中。如果无法验证令牌,则拒绝请求。

适用于 SDK >=3.14.0

要安装所需的最低 NodeJS 依赖项:

npm install firebase-functions@">=3.14.0"
npm install firebase-admin@">=9.8.0"

最后,但并非最不重要的......甚至还有一个调试助手:

dependencies {
    debugImplementation "com.google.firebase:firebase-appcheck-debug:16.0.0-beta02"
}

推荐阅读