Столкновение с проблемой вызова облачной функции из облачной задачи с помощью oidcToken

Я столкнулся с проблемой вызова облачной функции из облачной задачи с помощью oidcToken.

Вот подробности моего IAM и кода:

const { CloudTasksClient } = require('@google-cloud/tasks');
const client = new CloudTasksClient();

//See https://cloud.google.com/tasks/docs/tutorial-gcf
module.exports = async (payload, scheduleTimeInSec) => {
  const project = process.env.GOOGLE_APPLICATION_PROJECTID;
  const queue = process.env.QUEUE_NAME;
  const location = process.env.QUEUE_LOCATION;
  const callBackUrl = https://asia-south2-trial-288318.cloudfunctions.net/cloud-function-node-expres/;

  // Construct the fully qualified queue name.
  const parent = client.queuePath(project, location, queue);

  const body = Buffer.from(JSON.stringify(payload)).toString('base64');

  const task = {
    httpRequest: {
      httpMethod: 'POST',
      url: callBackUrl,
      headers: { 'Content-Type': 'application/json' },
      body
    },
    scheduleTime: {
      seconds: scheduleTimeInSec,
    }
  };

  if (process.env.GOOGLE_APPLICATION_SERVICE_ACCOUNT_EMAIL) {
    task.httpRequest.oidcToken = {
      serviceAccountEmail: process.env.GOOGLE_APPLICATION_SERVICE_ACCOUNT_EMAIL
    }
  }

  const request = {
    parent: parent,
    task: task,
  };

  // Send create task request.
  try {
    let [responses] = await client.createTask(request);

    return ({ sts: true, taskName: responses.name, msg: "Email Schedule Task Created" })
  }
  catch (e) {
    return ({ sts: true, err: true, errInfo: e, msg: "Unable to Schedule Task. Internal Error." })
  }
}

Process.env.GOOGLE_APPLICATION_SERVICE_ACCOUNT_EMAIL имеет роль вызывающего облачных функций, а облачная функция имеет член allAuthenticatedUsers с ролью вызывающий облачные функции согласно doc.

Но все же я вижу ответ 401, полученный облачной задачей, и облачная функция не вызывается (см. Изображение ниже):

введите описание изображения здесь

Любые комментарии по этому поводу, что здесь не так


person Chandrajyoti Das    schedule 17.11.2020    source источник


Ответы (1)


Похоже, это связано с тем, что вы создали функцию в Firebase (догадываясь по URL-адресу). Кажется, что Cloud Functions Invoker недостаточно для функций Firebase. Я воспроизвел аналогичное поведение функции HelloWorld из Firebase. Ошибка отличается (403), но я надеюсь, что это поможет вам устранить неполадки таким же образом.

После создания helloWorld в Firebase я протестировал его с помощью команды glcoud, выполнив следующие шаги:

  1. Создайте сервисный аккаунт с ролью Cloud Functions Invoker или воспользуйтесь выходом из него.
  2. Скачать ключ для аккаунта в формате JSON.
  3. Измените gcloud, чтобы он действовал как учетная запись службы:
gcloud auth activate-service-account <service-account@email> --key-file=<key-form-step-2.json>
  1. gcloud functions call helloWorld

В результате последнего действия я получил такую ​​ошибку:

ERROR: (gcloud.functions.call) ResponseError: status=[403], code=[Forbidden], message=[Permission 'cloudfunctions.functions.call' denied on resource 'projects/functions-asia-test-vitooh/locations/us-central1/functions/helloWorld' (or reso
urce may not exist).]

Итак, я создал пользовательскую роль в IAM: Cloud Functions Invoker + Firebase, добавив разрешение из сообщения об ошибке cloudfunctions.functions.call.

Функция начала работать с тем же gcloud functions call:

executionId: 3fgndpolu981
result: Hello from Firebase!

Думаю, это тоже сработает. Вы можете попробовать добавить такое же разрешение. Если это не сработает, попробуйте то же самое тестирование.

Использованная литература:

person vitooh    schedule 17.11.2020
comment
@vitooth, Большое спасибо за ваше драгоценное время и создание примеров, я постараюсь сообщить вам об этом. Извините за поздний ответ, я был занят другой работой. - person Chandrajyoti Das; 12.12.2020