Почему мне нужно жестко задавать учетные данные для подключения к AWS с помощью SDK для javascript?

Я спросил здесь этот другой вопрос, что наводит меня на мысль, что по умолчанию JavaScript AWS SDK ищет учетные данные в нескольких местах в вашей среде, и вам не нужно ничего делать. Порядок мест, которые он проверяет, указан здесь: https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html.

У меня есть рабочий код, который подключается к AWS Athena. Я могу заставить его работать только в том случае, если я жестко запрограммирую учетные данные вручную, что, похоже, противоречит приведенной выше документации. Вот мой код:

export const getAthena = (): AWS.Athena => {
    if (process.env["LOCAL_MODE"] === "true") {
        const awsCredentials = {
            region: "us-east-1",
            accessKeyId: awsCredentialsParser("aws_access_key_id"),
            secretAccessKey: awsCredentialsParser("aws_secret_access_key"),
            sessionKey: awsCredentialsParser("aws_session_token")
        };
        AWS.config.update(awsCredentials);
        let credential = new AWS.Credentials({
            accessKeyId: awsCredentials.accessKeyId,
            secretAccessKey: awsCredentials.secretAccessKey,
            sessionToken: awsCredentials.sessionKey
        });
        return new AWS.Athena({credentials: credential, signatureCache: false});
    } else {
        const awsCredentials1 = {
            region: "us-east-1",
            accessKeyId: undefined,
            secretAccessKey: undefined,
            sessionKey: undefined
        };
        AWS.config.update(awsCredentials1);
        return new AWS.Athena({credentials: undefined, signatureCache: false});
    }
};

export const awsCredentialsParser = (key: string): string => {
    const homeDirectory = os.homedir();
    const awsCredentials = fs.readFileSync(homeDirectory + "/.aws/credentials", {encoding: "UTF8"});
    const awsCredentialLines = awsCredentials.split("\n");
    const lineThatStartsWithKey = awsCredentialLines.filter((line) => line.startsWith(key))[0];
    return lineThatStartsWithKey.split(" = ")[1];
};

Как видите, я использую переменную среды под названием «LOCAL_MODE». Если установлено значение true, он получает учетные данные из моего общего файла учетных данных. Принимая во внимание, что если вы не находитесь в локальном режиме, он устанавливает для всех учетных данных значение undefined и вместо этого полагается на роль IAM. Разве в документации не сказано, что мне не нужно этого делать?

Но если я изменю свой код на это, любой вызов афины зависнет, пока не истечет время ожидания:

export const getAthena = (): AWS.Athena => {
    return new AWS.Athena();
};

Если я установлю тайм-аут на действительно большое число, это в конечном итоге сообщит мне, что у меня недействительные учетные данные.

Согласно документации, разве второй пример не должен находить учетные данные так же, как и первый? Почему второй пример зависает? Я не хочу писать код выше. Как заставить мой код работать, как в примерах?

  1. Я как-то создаю AWS.Athena() неправильно во 2-м примере?
  2. Как устранить неполадки, чтобы понять, почему он зависает?
  3. Согласно документации, разве нижний пример не должен делать то же самое, что и верхний?

Эти два фрагмента работают по-разному, если у вас есть конкурирующие источники учетных данных. Согласно документам, учетные данные извлекаются из различных источников: IAM, файл credentials, переменные env и т. д. В документах ничего не говорится о приоритете, но он должен каким-то образом (детерминистически) решить, что использовать. Итак, ваше соединение зависает, потому что оно использует учетные данные с более высоким приоритетом, которые оказались недействительными, верно? Я предполагаю, что это из-за смены региона.

freakish 30.07.2019 21:10

@freakish, насколько я могу судить, нет. Локально, я думаю, у меня есть только файл учетных данных. Опять же, я мало знаю об IAM в целом. Может ли мой локальный компьютер иметь роль IAM, если он подключен к VPN? Я думал, что роли IAM применяются только к серверам/сервисам AWS.

Daniel Kaplan 30.07.2019 21:12

Да, я не думаю, что IAM имеет значение, если вы не настроили его явно. Хотя я тоже не эксперт IAM. В любом случае, я думаю, что проблема связана с настройкой региона. Потому что вы не можете подключиться. С неверными учетными данными вы получите сообщение об ошибке относительно быстро. Пробовали ли вы вызывать new AWS.Athena({region: "us-east-1"}) или обновлять только регион перед созданием нового экземпляра AWS.Athena?

freakish 30.07.2019 21:22

@freakish Да, и время истекает так же.

Daniel Kaplan 30.07.2019 22:34

Странный. У вас есть более одного профиля в вашей конфигурации учетных данных? Если да, то по умолчанию первый?

freakish 30.07.2019 22:41

@причудливый хороший вопрос. У меня только один называется [aws14]. Я переименовал его в [default], и он работал, как и ожидалось. Большое спасибо за помощь!

Daniel Kaplan 30.07.2019 22:45
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
6
805
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Если вы используете роль IAM, вам не нужно явно указывать какие-либо учетные данные, нулевые или иные:

const AWS = require('aws-sdk');
const athena = new AWS.Athena();
const params = { ... };
const rc = await athena.startQueryExecution(params).promise();

Фактически, это работает с учетными данными, предоставленными через локальные переменные среды или в файле учетных данных/конфигурации. Есть цепочка поставщиков учетных данных, которые SDK будет пробовать один за другим.

Я не использую роль IAM локально (по крайней мере, не намеренно). Я использую роль IAM только при развертывании кода. Мой пример в значительной степени уже показывает то, что вы сказали здесь (у вас есть 2 дополнительные строки).

Daniel Kaplan 30.07.2019 22:35

Вам не нужно больше кода, чем я показал. Что произойдет, если вы локально запустите awscli: aws s3 ls и aws athena list-named-queries? Истечет ли время ожидания?

jarmod 30.07.2019 22:45

Проверьте комментарии к ОП. Проблема в том, что в моем файле учетных данных есть только один профиль, но он не назван [default]. Знаете, как я могу сказать, что хочу использовать профиль с именем [aws14] вместо [default]?

Daniel Kaplan 30.07.2019 22:48

На Mac или Linux: AWS_PROFILE=aws14 node app.js

jarmod 31.07.2019 01:00
Ответ принят как подходящий

Итак, после расследования кажется, что это (т.е. сбой во втором фрагменте) связано с тем, что у вас нет профиля [default] в вашем файле .aws/credentials. Это специальный профиль. Я предполагаю, что клиент использует пустые строки (или нули или что-то еще), когда он не может их найти. Что я нахожу забавным, если честно (должно быть исключение).

В любом случае, чтобы исправить это, либо переименуйте профиль, который вам нужно [default], либо настройте другой профиль в своем коде. Вот соответствующие документы:

https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-shared.html

Я рекомендую использовать переменную окружения AWS_PROFILE. Сделает ваш код более переносимым.

Другие вопросы по теме