Geo*_*gii 1 authentication firebase gcloud google-cloud-functions google-iam
我有通过部署的简单测试可调用函数firebase deploy --only functions。
这是内容:
export const test = region('europe-west1').https.onCall((data, context) => {
logger.debug('test call info', data, context);
return 'hello, world!';
});
Run Code Online (Sandbox Code Playgroud)
我可以通过 HTTP 调用https://europe-west1-{project}.cloudfunctions.net/test并接收来成功调用它{"result": "hello, world!"}。
现在想通过 IAM 策略来保护此功能。
allUsersCloud Functions Invoker 角色中删除,并使用 Cloud Functions Invoker 角色添加在 #1 中创建的服务帐户。<--- 现在,当我尝试调用我的测试函数时,如预期的那样,我收到 403 Forbiddenconst auth = new GoogleAuth({keyFile: './key.json'});
targetAudience = new URL('https://europe-west1-{project}.cloudfunctions.net/test');
const client = await auth.getIdTokenClient(targetAudience as string);
const idToken = await client.idTokenProvider.fetchIdToken(targetAudience as string);
console.log(idToken);
Run Code Online (Sandbox Code Playgroud)
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={{id-token}}。Authorization: Bearer {{id-token}}标头调用我的端点。{
"error": {
"message": "Unauthenticated",
"status": "UNAUTHENTICATED"
}
}
Run Code Online (Sandbox Code Playgroud)
UPD1:向@DazWilkin 提供附加信息
1.
gcloud auth activate-service-account cloud-functions-invoker@{project-id}.iam.gserviceaccount.com --key-file="key.json"
Activated service account credentials for: [cloud-functions-invoker@{project-id}.iam.gserviceaccount.com]
Run Code Online (Sandbox Code Playgroud)
gcloud projects get-iam-policy {project-id}
...
- members:
- serviceAccount:cloud-functions-admin@{project-id}.iam.gserviceaccount.com
- serviceAccount:cloud-functions-invoker@{project-id}.iam.gserviceaccount.com
role: roles/cloudfunctions.invoker
...
Run Code Online (Sandbox Code Playgroud)
gcloud auth print-identity-token | cliphttps://www.googleapis.com/oauth2/v3/tokeninfo?id_token={{id-token}}{
"aud": "32555940559.apps.googleusercontent.com",
"azp": "cloud-functions-invoker@{project-id}.iam.gserviceaccount.com",
"email": "cloud-functions-invoker@{project-id}.iam.gserviceaccount.com",
"email_verified": "true",
"exp": "1629157648",
"iat": "1629154048",
"iss": "https://accounts.google.com",
"sub": "114693730231812960252",
"alg": "RS256",
"kid": "6ef4bd908591f697a8a9b893b03e6a77eb04e51f",
"typ": "JWT"
}
Run Code Online (Sandbox Code Playgroud)
curl --location --request POST 'https://europe-west1-{project-id}.cloudfunctions.net/test' \
--header 'Authorization: Bearer
{token}
' \
--header 'Content-Type: application/json' \
--data-raw '{
"data": {
"goodbye": "world:("
}
}'
Run Code Online (Sandbox Code Playgroud)
UPD2:新输入
仅在可调用函数中才会观察到此行为https.onCall()。如果我使用的https.onRequest()东西工作正常,但我仍然对onCall行为感到困惑,因为我似乎正确地实现了协议(参见我的卷曲)。
我的天啊!!!!!
TL;DR:可调用函数仅适用于通过 firebase auth 进行身份验证的最终用户,并且不能与 IAM 令牌一起使用。使用它们的唯一方法是roles/cloudfunctions.invoker分配给allUsers。
问题是......我在这里研究可调用函数协议规范: https: //firebase.google.com/docs/functions/callable-reference。
它说:
对可调用触发器端点的 HTTP 请求必须是具有以下标头的 POST:
...
- 可选:授权:持有者
- 发出请求的登录用户的 Firebase 身份验证用户 ID 令牌。后端自动验证此令牌并使其在处理程序的上下文中可用。如果令牌无效,则请求被拒绝。
我认为规范意味着我们将在这里传递我们的服务帐户id-token,并且我正在尝试这样做(例如使用onRequest函数)。但突然间,token 在那里的解释有所不同。它是通过 firebase 身份验证获得的用户令牌。甚至在文档中还进行了更深入的说明(1、2):
警告:Firebase 管理 SDK 中包含的 ID 令牌验证方法旨在验证来自客户端 SDK 的 ID 令牌,而不是您使用管理 SDK 创建的自定义令牌。有关详细信息,请参阅身份验证令牌。
错过这个警告让我损失了三天的痛苦。
| 归档时间: |
|
| 查看次数: |
3052 次 |
| 最近记录: |