Google 云函数中的 JWT 身份验证

JWT Authentication in Google Cloud Functions

在使用 Google 云函数中的模块 "googleapis" 调用时,我无法解决来自 Google 数据流 API 的 403 响应的原因。

当我的电脑上 运行 使用与 Cloud Functions 上 运行 相同的代码时,该代码有效。 正在从存储在 Google 存储桶中的对象中检索 JWT .json 文件。

代码如下所示:

...
return getToken(). //Retrieves the JWT Client from Google Storage
      then(function (jwtToken) {
        console.log("Token: ", JSON.stringify(jwtToken));
        return dataFlowList({
          projectId: adc.projectId,
          auth: jwtToken,
          filter: "TERMINATED"
        }).then(list => filterDataflowJobList(list))
...

这里是getToken函数:

...
let storage: CloudStorage.Storage = CloudStorage({
  projectId: adc.projectId
});
var bucket: CloudStorage.Bucket = storage.bucket(bucketName);

var bucketGetFiles = PromiseLab.denodeify(bucket.getFiles);

var stream = bucket.file(jwtJsonFileName).createReadStream();
return toString(stream)
  .then(function (msg) {
    var jsonJwt = JSON.parse(msg);
    var jwtClient = new google.auth.JWT(
      jsonJwt.client_email,
      null,
      jsonJwt.private_key,
      ['https://www.googleapis.com/auth/cloud-platform'], // an array of auth scopes
      null
    );
    return jwtClient;
  }).catch(function (error) {
    console.log("Error while trying to retrieve JWT json");
    throw error;
  })
}
...

我在欧盟工作,而 Cloud Functions 受美国约束,是这样吗? 数据流工作在美国也有 运行

虽然 运行 在 Google 函数上,但我使用的身份验证检索方法未检索 projectId,因此未经授权。

async function getADC() {
  // Acquire a client and the projectId based on the environment. This method looks
  // for the GCLOUD_PROJECT and GOOGLE_APPLICATION_CREDENTIALS environment variables.
  const res = await auth.getApplicationDefault();
  let client = res.credential;

  // The createScopedRequired method returns true when running on GAE or a local developer
  // machine. In that case, the desired scopes must be passed in manually. When the code is
  // running in GCE or a Managed VM, the scopes are pulled from the GCE metadata server.
  // See https://cloud.google.com/compute/docs/authentication for more information.
  if (client.createScopedRequired && client.createScopedRequired()) {
    // Scopes can be specified either as an array or as a single, space-delimited string.
    const scopes = ['https://www.googleapis.com/auth/cloud-platform'];
    client = client.createScoped(scopes);
  }
  return {
    client: client,
    projectId: res.projectId
  }
}

我是通过查看错误日志中的 Header 请求发现的,它的形式为:url: 'https://dataflow.googleapis.com/v1b3/projects//jobs'(注意项目和项目之间的双“//”职位。