Неверный запрос AWS S3 — 400 при отправке файла по предварительно подписанному URL

#amazon-web-services #amazon-s3

#amazon-web-services #amazon-s3

Вопрос:

Мой запрос выглядит следующим образом:

https://{my-bucket-name}.s3.amazonaws.com /{идентификатор пользователя}/{название изображения}.jpeg?AWSAccessKeyId={ключ} amp; Тип содержимого = изображение/jpeg amp; Срок действия = 1597576628 amp;Подпись ={signature}

где {части} просто подвергнуты цензуре, но в исходном ответе выглядят правильно, точно так же, как в руководстве, которое я делаю.

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

     {
        "Sid": "{sid}",
        "Action": [
            "s3:GetObject"
        ],
        "Effect": "Allow",
        "Resource": "arn:aws:s3:::{my-bucket-name}/*",
        "Principal": "*"
    }
  

Итак, в чем может быть проблема?

РЕДАКТИРОВАТЬ: добавление putObject в политику не помогло. Я загружаю файл таким образом, напрямую из React-клиента:

   const upload = await axios.put(uploadConfig.data.url, file, {
    headers: {
      'Content-Type': file.type
    }
  })
  

И я генерирую предварительно подписанный URL-адрес следующим образом (обратите внимание на операцию putObject):

     s3.getSignedUrl('putObject', {
        Bucket: '{my-bucket-name}',
        ContentType: 'image/jpeg',
        Key: key
    }, (err, url) => res.send({key, url}));
  

Дополнительные заголовки запроса, установленные промежуточным программным обеспечением / браузером, являются:

 Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en,de;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 104221
Content-Type: image/jpeg
Host: {my-bucket-name}.s3.amazonaws.com
Origin: http://localhost:3000
Pragma: no-cache
Referer: http://localhost:3000/blogs/new
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla....
  

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

1. Как загрузить файл с предварительно подписанным URL?

2. @Phil, я удалил свой ответ. это было неправильно. потому что вы никогда не должны разрешать общедоступный доступ на запись. если учетные данные IAM, используемые для создания предварительно подписанного URL-адреса, имеют достаточное разрешение для загрузки файла, предварительно подписанный URL-адрес также должен работать.

3. кроме того, если ваш предварительно подписанный URL сгенерирован для getObject , вы не сможете выполнить putObject операцию с использованием этого предварительно подписанного URL

4. @ArunK Я выполняю это руководство: udemy.com/course/advanced-node-for-developers где преподаватель объясняет, что публичный доступ разрешен, поскольку мы хотим прямую загрузку с клиента, не тратя процессорное время нашего серверной части, во время загрузки. Для меня это кажется разумным, если вы проверяете только расширения файлов и в любом случае не выполняете глубокую проверку файлов.

5. я имел в виду, что предоставление putObject разрешений для каждого из них в политике корзины является неправильным. загрузка с использованием предварительно подписанного URL-адреса является правильным способом. публичное чтение допустимо, если вы согласны поделиться своими файлами со всем миром.

Ответ №1:

Please use AWS4-HMAC-SHA256. в сообщении об ошибке предлагается использовать версию подписи v4. похоже, что сгенерированная подпись в предварительно подписанном URL-адресе не является версией 4. возможно, версия подписи v2

пожалуйста, попробуйте указать версию подписи при генерации URL-адреса, как показано ниже.

 const s3 = new AWS.S3({signatureVersion: 'v4'})
  

Также убедитесь, что вы используете версию aws-sdk, превышающую 2.68.0 указанную в документации

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

1. Спасибо, теперь это работает. Версию 4 я сам отключил, но обновление пакета сэкономило мне некоторое время 🙂 Еще одна вещь, которую мне пришлось добавить, — пользовательский регион: new AWS.S3({ accessKeyId, secretAccessKey, signatureVersion: 'v4', region: 'eu-central-1' });

2. Да, вы поняли версию 4. Опубликовал ответ, чтобы помочь другим в такой же ситуации. Пожалуйста, отправьте ответ, если хотите.

3. Нет, нет, все в порядке, как я уже сказал, вы мне очень помогли, все заслуги перед вами, спасибо 🙂