Firebase Functions AppCheck 总是让我的设备失败
Firebase Functions AppCheck keeps failing my device
我一直在尝试将 AppCheck 与我的 Android 应用程序集成,但我似乎无法提出有效请求。
为了测试,我一直使用下面的代码:
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 控制台,但无论我做什么,如果它是模拟器或物理设备,当我调用函数时,failed-precondition总是抛出异常。
查看功能日志,我发现该应用程序丢失了:
文档我已经看了好几遍了,似乎不能漏掉任何一步。我是不是遗漏了什么或者我能做些什么来找到根本原因?
感谢您的宝贵时间!
编辑:
关于 Martin 的建议,我创建了一个新的 OnRequest 函数并添加了 X-Firebase-AppCheck header。我正确地收到了令牌并且能够通过以下方式成功验证它:
firebaseAdmin.appCheck().verifyToken(appCheckToken)
所以,我的猜测是 Android 没有将 X-Firebase-AppCheck 自动添加到 OnCall 函数就像它应该的那样。
我运行代码,通过代码打了一些断点,注意到了以下几点。 Firebase 的 call 方法正在添加 Firebase-Instance-ID-Token 但我似乎找不到 X-Firebase-AppCheck header 任何地方。也许我不应该看到这个值,或者我只是找不到添加它的位置。或者可能根本没有添加,因此我根本无法验证我的 context.app。
可能需要获得 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,
...
);
其中 FirebaseFunctions.getInstance().getHttpsCallable().call()
没有说明如何或是否必须明确设置 X-Firebase-AppCheck
header。 Cloud Functions 通常应该收到 X-Firebase-AppCheck
header - 以及之前检索到的 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');
}
也可以发行自己的代币……checking for context-app
也是有效的。
更新:Protocol specification for https.onCall 内容为:
Optional: X-Firebase-AppCheck: <token>
The Firebase App Check token provided by the client app making the request. The backend automatically verifies this token and decodes it, injecting the appId in the handler's context. If the token cannot be verified, the request is rejected.
Available for 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"
}
在测试一切都没有成功之后,我孤注一掷,试图查看不相关的文件并找到了解决方案。
在我的 build.gradle 中,我使用 bom 导入所有 Firebase 依赖项:
implementation platform("com.google.firebase:firebase-bom:27.0.0")
implementation "com.google.firebase:firebase-crashlytics-ktx"
implementation "com.google.firebase:firebase-analytics-ktx"
implementation "com.google.firebase:firebase-firestore-ktx"
implementation "com.google.firebase:firebase-functions-ktx"
implementation "com.google.firebase:firebase-auth-ktx"
所以我想:“firebase-bom 可以导入过时的 functions-ktx 依赖项吗?”
你猜怎么着?一旦我导入了没有 bom 的依赖项,我就开始看到添加了 X-Firebase-AppCheck 和 context.app有效。
我得到了以下 build.gralde:
implementation "com.google.firebase:firebase-crashlytics-ktx:18.2.1"
implementation "com.google.firebase:firebase-analytics-ktx:19.0.0"
implementation "com.google.firebase:firebase-firestore-ktx:23.0.3"
implementation "com.google.firebase:firebase-functions-ktx:20.0.0"
implementation "com.google.firebase:firebase-auth-ktx:21.0.1"
经过更多调查,我发现我使用的是过时的 firebase-bom 版本。 Android Studio 曾经让我知道依赖项是否有新版本,但它没有注意到 firebase-bom。事实证明,我只需要更新我的 firebase-bom 依赖项。
TL;DR
检查您的 Android Firebase 库版本!
我一直在尝试将 AppCheck 与我的 Android 应用程序集成,但我似乎无法提出有效请求。
为了测试,我一直使用下面的代码:
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 控制台,但无论我做什么,如果它是模拟器或物理设备,当我调用函数时,failed-precondition总是抛出异常。
查看功能日志,我发现该应用程序丢失了:
文档我已经看了好几遍了,似乎不能漏掉任何一步。我是不是遗漏了什么或者我能做些什么来找到根本原因?
感谢您的宝贵时间!
编辑:
关于 Martin 的建议,我创建了一个新的 OnRequest 函数并添加了 X-Firebase-AppCheck header。我正确地收到了令牌并且能够通过以下方式成功验证它:
firebaseAdmin.appCheck().verifyToken(appCheckToken)
所以,我的猜测是 Android 没有将 X-Firebase-AppCheck 自动添加到 OnCall 函数就像它应该的那样。
我运行代码,通过代码打了一些断点,注意到了以下几点。 Firebase 的 call 方法正在添加 Firebase-Instance-ID-Token 但我似乎找不到 X-Firebase-AppCheck header 任何地方。也许我不应该看到这个值,或者我只是找不到添加它的位置。或者可能根本没有添加,因此我根本无法验证我的 context.app。
可能需要获得 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,
...
);
其中 FirebaseFunctions.getInstance().getHttpsCallable().call()
没有说明如何或是否必须明确设置 X-Firebase-AppCheck
header。 Cloud Functions 通常应该收到 X-Firebase-AppCheck
header - 以及之前检索到的 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');
}
也可以发行自己的代币……checking for context-app
也是有效的。
更新:Protocol specification for https.onCall 内容为:
Optional:
X-Firebase-AppCheck: <token>
The Firebase App Check token provided by the client app making the request. The backend automatically verifies this token and decodes it, injecting the appId in the handler's context. If the token cannot be verified, the request is rejected.
Available for 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"
}
在测试一切都没有成功之后,我孤注一掷,试图查看不相关的文件并找到了解决方案。
在我的 build.gradle 中,我使用 bom 导入所有 Firebase 依赖项:
implementation platform("com.google.firebase:firebase-bom:27.0.0")
implementation "com.google.firebase:firebase-crashlytics-ktx"
implementation "com.google.firebase:firebase-analytics-ktx"
implementation "com.google.firebase:firebase-firestore-ktx"
implementation "com.google.firebase:firebase-functions-ktx"
implementation "com.google.firebase:firebase-auth-ktx"
所以我想:“firebase-bom 可以导入过时的 functions-ktx 依赖项吗?”
你猜怎么着?一旦我导入了没有 bom 的依赖项,我就开始看到添加了 X-Firebase-AppCheck 和 context.app有效。
我得到了以下 build.gralde:
implementation "com.google.firebase:firebase-crashlytics-ktx:18.2.1"
implementation "com.google.firebase:firebase-analytics-ktx:19.0.0"
implementation "com.google.firebase:firebase-firestore-ktx:23.0.3"
implementation "com.google.firebase:firebase-functions-ktx:20.0.0"
implementation "com.google.firebase:firebase-auth-ktx:21.0.1"
经过更多调查,我发现我使用的是过时的 firebase-bom 版本。 Android Studio 曾经让我知道依赖项是否有新版本,但它没有注意到 firebase-bom。事实证明,我只需要更新我的 firebase-bom 依赖项。
TL;DR
检查您的 Android Firebase 库版本!