无法使用用户认证令牌调用HTTP Cloud Function问题求助
问题分析与解决方案
你遇到的错误核心原因是:Firebase Callable Functions 的请求验证逻辑和普通 Cloud Function 不同——它不仅要求调用者具备 Cloud IAM 权限,还强制要求请求携带 Firebase App 标识,且认证令牌必须是 Firebase ID Token(而非 gcloud 生成的 Google Cloud 身份令牌)。你用 gcloud auth print-identity-token 获取的令牌属于 Google Cloud 生态的身份凭证,无法通过 Callable 函数的 Firebase 专属验证,同时请求体里缺少 Firebase App 信息,才会出现 app: MISSING 和 auth: INVALID 的错误。
以下是几种可行的解决方法:
方法1:使用 Firebase ID Token 调用(模拟真实用户场景)
这是符合 Callable 函数设计预期的测试方式,步骤如下:
- 确保已安装并初始化 Firebase CLI,登录你的 Firebase 项目
- 获取测试用的 Firebase ID Token:
# 登录并获取当前用户的 ID Token firebase auth:login --no-localhost firebase auth:print-id-token - 修改 curl 命令,替换令牌并补充 Firebase App 信息:
注:Firebase App ID 可在 Firebase 控制台「项目设置」中找到curl -m 130 -X POST https://us-central1-my-project.cloudfunctions.net/myFunction \ -H "Authorization: bearer $(firebase auth:print-id-token)" \ -H "Content-Type: application/json" \ -d '{"data": {"recId": "6lKMe3XgbBQ6hvba5N1j"}, "app": {"appId": "你的Firebase App ID", "projectId": "你的项目ID"}}'
方法2:调整函数验证逻辑(适配后端服务调用)
如果你的调用方是 Google Cloud 内部服务(如其他 Cloud Function),可以手动修改函数,允许接受 Google Cloud 身份令牌:
from firebase_functions import https_fn import google.auth.transport.requests import google.oauth2.id_token @https_fn.on_call() def my_function(req: https_fn.CallableRequest) -> Any: # 手动验证 Google Cloud 身份令牌 auth_header = req.headers.get("Authorization") if auth_header and auth_header.startswith("Bearer "): token = auth_header.split(" ")[1] try: # 验证令牌,指定函数的 URL 作为受众 id_info = id_token.verify_oauth2_token( token, google.auth.transport.requests.Request(), audience="https://us-central1-my-project.cloudfunctions.net/myFunction" ) except ValueError: raise https_fn.HttpsError( code=https_fn.FunctionsErrorCode.UNAUTHENTICATED, message="Invalid token" ) # 原有业务逻辑 try: recId = req.data["recId"] return {"passedRecId": recId} except (ValueError, KeyError): raise https_fn.HttpsError( code=https_fn.FunctionsErrorCode.INVALID_ARGUMENT, message="The function was called with incorrect arguments" )
方法3:改用普通 HTTP Cloud Function(简化测试)
如果不需要 Callable 函数的自动参数解析、标准化错误返回等特性,可以将函数改为普通 HTTP 触发,这样原有的 gcloud 令牌就能正常调用:
from firebase_functions import https_fn @https_fn.on_request() def my_function(req: https_fn.Request) -> https_fn.Response: if req.method != "POST": return https_fn.Response(status=405) try: data = req.get_json() recId = data["recId"] return https_fn.Response(json={"passedRecId": recId}, status=200) except (ValueError, KeyError): return https_fn.Response(json={"error": "Incorrect arguments"}, status=400)
内容的提问来源于stack exchange,提问作者soogui
相关产品推荐
相关产品推荐

