尝试通过 Cloud Scheduler 调用使用 firebase-admin 对服务帐户进行身份验证?错误:Firebase ID 令牌具有不正确的“iss”(颁发者)声明

cbd*_*per 0 firebase service-accounts google-iam google-cloud-scheduler google-cloud-run

我正在尝试验证从 Cloud Scheduler cron 作业对我的服务器(在 Cloud Run 上)进行的 API 调用。

我正在尝试使用服务帐户来实现此目的。

注意:这一切都发生在同一个项目内。

参考:

这就是我正在做的:

第 1 步- 创建服务帐户

我访问https://console.cloud.google.com/apis/credentials并创建了一个新的服务帐户。我已将角色指定为owner

在此输入图像描述

第 2 步- 创建 cron 作业。

我像往常一样访问https://console.cloud.google.com/cloudscheduler创建 cron 作业。

在此输入图像描述

在该service account字段中,我输入了我的服务帐户电子邮件。在该Audience字段中,我输入了我的项目 id,因为在某些时候我收到一条错误,指出它期望它是我的项目 id 的名称。

这是错误:

Firebase ID 令牌的“aud”(受众)声明不正确。预期的"PROJECT_ID"

第 3 步- 运行作业并识别解码令牌:

这是我服务器上的代码:

import * as admin from "firebase-admin";

admin.initializeApp({
  credential: admin.credential.cert(
    // THIS IS THE DEFAULT FIREBASE-ADMIN SERVICE ACCOUNT
    // THAT IS AUTOMATICALLY CREATED BY FIREBASE
    SERVICE_ACCOUNT as admin.ServiceAccount
)});

// THIS IS THE CODE THAT IS INSIDE MY SERVER TRYING TO VERIFY THE SERVICE ACCOUNT

try {
  const authHeader = req.headers.authorization;
  console.log(`authHeader: ${authHeader}`);
  if (authHeader) {
    const idToken = authHeader.split(" ")[1];   // GETS THE USER ID TOKEN
    const decodedToken = await admin.auth().verifyIdToken(idToken);
    console.log(`decodedToken: ${decodedToken}`);
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我目前收到的错误:

Firebase ID 令牌的“iss”(颁发者)声明不正确。应为“https://securetoken.google.com/”my-project-id”,但得到的是“https://accounts.google.com”。确保 ID 令牌来自与用于的服务帐户相同的 Firebase 项目验证此 SDK。有关如何检索 ID 令牌的详细信息,请参阅https://firebase.google.com/docs/auth/admin/verify-id-tokens 。

我这样做的方式有什么问题吗?我不应该使用 firebase-admin 吗?

我应该使用google-auth-library令牌来验证吗?

在此输入图像描述

cbd*_*per 7

经过一上午的地狱般的尝试调试之后,这是我发现的。

看来这firebase-adminadmin.auth().verifyIdToken()适用于从firebaseSDK 生成的令牌。

我直接使用它就可以工作了google-auth-library

我做了以下事情。

注意:代码的其余部分是相同的(使用问题中描述的相同服务帐户):

import { OAuth2Client } from "google-auth-library";

export const apiExpressRouteHandler: RequestHandler = async (req, res) => {
  try {

    const PROJECT_ID = process.env.PROJECT_ID;

    const authHeader = req.headers.authorization;
    if (authHeader) {
      const client = new OAuth2Client(PROJECT_ID);
      const ticket = await client.verifyIdToken({
        idToken: authHeader.split(" ")[1],
        audience: PROJECT_ID
      });

      // LOGGING ticket PROPERTIES

      console.log(`userId: ${JSON.stringify(ticket.getUserId())}`);
      console.log(`payload: ${JSON.stringify(ticket.getPayload())}`);
      console.log(`envelope: ${JSON.stringify(ticket.getEnvelope())}`);
      console.log(`attributes: ${JSON.stringify(ticket.getAttributes())}`);
    }

    // REST OF THE CODE
  }
} 
catch(err) {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

我不确定是否PROJECT_ID有必要初始化客户端,new OAuth2Client(PROJECT_ID);但它是这样工作的。