GCP App Engine — не удалось загрузить учетные данные по умолчанию

#authentication #google-app-engine #google-cloud-platform #google-authentication #service-accounts

#аутентификация #google-app-engine #google-облачная платформа #google-аутентификация #сервис-учетные записи

Вопрос:

Я работаю над проектом, который использует GCP и App Engine. В dev он выведет ошибки, в которых говорится:

 2020-09-20 15:07:24 dev[development]  Error: Could not load the default credentials. Browse 
to https://cloud.google.com/docs/authentication/getting-started for more information.      
at GoogleAuth.getApplicationDefaultAsync (/workspace/node_modules/google-auth-
library/build/src/auth/googleauth.js:161:19)      at runMicrotasks (<anonymous>)      at 
processTicksAndRejections (internal/process/task_queues.js:97:5)      at runNextTicks 
(internal/process/task_queues.js:66:3)      at listOnTimeout (internal/timers.js:518:9)      
at processTimers (internal/timers.js:492:7)      at async GoogleAuth.getClient 
(/workspace/node_modules/google-auth-library/build/src/auth/googleauth.js:503:17)      at 
async GrpcClient._getCredentials (/workspace/node_modules/google-
gax/build/src/grpc.js:108:24)      at async GrpcClient.createStub 
(/workspace/node_modules/google-gax/build/src/grpc.js:229:23)
  

Имейте в виду, что это режим разработки, но он запущен в инфраструктуре GCP App Engine, он не запускается на локальном хосте. Я просматриваю журналы с помощью команды:

 gcloud app logs tail -s dev
  

Согласно документам GCP App Engine @ https://cloud.google.com/docs/authentication/production#cloud-console

 If your application runs inside a Google Cloud environment that has a default service 
account, your application can retrieve the service account credentials to call Google Cloud 
APIs.
  

Я проверил свои учетные записи службы app Engine. И у меня есть учетная запись службы по умолчанию, и она активна. Пожалуйста, посмотрите отредактированное изображение здесь:

учетная запись службы app Engine по умолчанию

Итак, я предполагаю, что мой вопрос: если у меня есть активная учетная запись службы по умолчанию, и мое приложение должно автоматически использовать ключ учетной записи службы по умолчанию при выполнении вызовов API, почему я вижу эту ошибку аутентификации? Что я делаю не так?

Редактировать: вот код, который выводит ошибки:

 async function updateCrawledOnDateForLink (crawlRequestKey: EntityKey, linkKey: EntityKey): Promise<void> {

  try {
        
    const datastore = new Datastore();
    
    const crawlRequest = await datastore.get(crawlRequestKey)
    
    const brand = crawlRequest[0].brand.replace(/s/g, "")
    
    await data.Link.update(
       linkKey.id,
      { crawledOn: new Date() },
      null,
      brand)
        
  } catch (error) {
        console.error('updateCrawledOnDateForLink ERROR:', `CrawlRequest: ${crawlRequestKey.id}`, `Link: ${linkKey.id}`, error.message)
  }
}
  

Я предполагаю, что проблема заключается в создании нового хранилища данных () каждый раз, но дайте мне знать ваши мысли.

Комментарии:

1. Отредактируйте свой вопрос и включите код, который генерирует ошибку.

2. Позвольте мне потратить некоторое время, чтобы сузить блок кода, который вызывает проблему. Я отвечу кодом, когда узнаю.

3. Хорошо, я обновил сообщение соответствующим кодом. Надеюсь, у вас есть некоторое представление.

4. еще 2 вопроса: Можете ли вы также поделиться своим файлом app.yaml? Можете ли вы поделиться своим файлом package.json? Спасибо

5. Удаление вызова new Datastore() для глобального в двух разных функциях (удаление локального вызова new Datastore()) привело к устранению проблемы. Я запускал приложение до завершения более 5 раз, и с тех пор оно не появлялось.

Ответ №1:

Тот факт, что удаление new Datastore() из нескольких функций решает проблему, указывает на то, что проблема связана не с аутентификацией с помощью App Engine, а с хранилищем данных, что подтверждает раздел документации, которым вы поделились.

Я считаю, что проблема заключается в том, что хранилище данных теряется с учетными данными, когда вы создаете несколько его экземпляров в своем коде по какой-то неизвестной причине.

Поскольку вы упомянули в комментариях, что вам на самом деле не нужно несколько экземпляров хранилища данных в вашем коде, решение вашей проблемы заключается в использовании одного экземпляра в глобальной переменной и использовании этой переменной в нескольких функциях.