awsasticsearch получает ошибку подписи по запросу - PullRequest
1 голос
/ 17 февраля 2020

Получил ошибку подписи 403 при использовании функции извлечения ниже:

    function elasticsearchFetch(AWS, elasticsearchDomain, endpointPath, options = {}, region = process.env.AWS_REGION) {
  return new Promise((resolve, reject) => {
    const { body, method = 'GET' } = options;
    const endpoint = new AWS.Endpoint(elasticsearchDomain);
    const request = new AWS.HttpRequest(endpoint, region);
    request.method = method;
    request.path += endpointPath;
    request.headers.host = elasticsearchDomain;
    if (body) {
      request.body = body;
      request.headers['Content-Type'] = 'application/json';
      request.headers['Content-Length'] = request.body.length;
    }
    const credentials = new AWS.EnvironmentCredentials('AWS');
    const signer = new AWS.Signers.V4(request, 'es');
    signer.addAuthorization(credentials, new Date());
    const client = new AWS.HttpClient();
    client.handleRequest(request, null, (res) => {
      let chunks = '';
      res.on('data', (chunk) => {
        chunks += chunk;
      });
      res.on('end', () => {
        if (res.statusCode !== 201) console.log('Got these options STATUSCODE', JSON.stringify(options, false, 2));
        return resolve({ statusCode: res.statusCode, body: chunks });
      });
    }, (error) => {
      console.log('Got these options ERROR', JSON.stringify(options, false, 2));
      return reject(error);
    });
  });
}

Это параметры, использованные для запроса в функции выше:

{
    "method": "POST",
    "body": "{\"prefix\":\"image_233/ArtService/articles-0/GB/ART-60297885/\",\"id\":\"ART-60297885\",\"retailUnit\":\"GB\",\"commercial\":{\"name\":{\"en-GB\":\"FÖRBÄTTRA\"}},\"schemaType\":\"product\",\"productType\":\"ART\"}"
}

и получил эту ошибку :

{
    "statusCode": 403,
    "body": "{\"message\":\"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.\"}"
}

Это конечная точка: 233/_doc/

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

Я считаю, что ваш заголовок Content-Length неверен, что приводит к несоответствию подписи.

  • Ваша полезная нагрузка содержит строку FÖRBÄTTRA, которая имеет два двухбайтовых символа.
  • Вы устанавливаете Content-Length на request.body.length, что соответствует 186.
  • Хотя равно числу символов в теле, оно равно не количество байтов в теле (188).

Чтобы вычислить Content-Length, используйте Buffer.byteLength(request.body). Для такого запроса POST вы можете даже полностью удалить эту строку кода, и запрос будет выполнен успешно.

  // Content-Length is only needed for DELETE requests that include a request
  // body, but including it for all requests doesn't seem to hurt anything.
  request.headers['Content-Length'] = Buffer.byteLength(request.body);

Источник: https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-request-signing.html#es -request-signature-node

0 голосов
/ 17 февраля 2020

Кстати, почему бы не использовать elasticsearch клиент для nodejs для связи сasticsearch, а не для написания собственных логи c. Вы можете рассмотреть возможность использования http-aws-es, которая выполняет часть подписания запроса для вас. Код будет выглядеть как

const { Client } = require("elasticsearch");
const esConnectionClass = require("http-aws-es");

const elasticsearchConfig = {
  host: "somePath",
  connectionClass: esConnectionClass
};

const nativeClient = new Client(elasticsearchConfig);

const result = await nativeClient.search({});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...