#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
операцию с использованием этого предварительно подписанного URL4. @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. Нет, нет, все в порядке, как я уже сказал, вы мне очень помогли, все заслуги перед вами, спасибо 🙂