Загрузка 400 плохих запросов в Amazon S3 с подписанным запросом - PullRequest
0 голосов
/ 03 апреля 2020

Я занимаюсь разработкой веб-приложения на Django и React, развернутого на Heroku, для которого требуется хранилище файлов. В соответствии с рекомендациями Heroku, я использую Amazon S3. Тем не менее, мне кажется, что я не могу загрузить файлы в мое ведро S3 с внешнего интерфейса. Согласно этим инструкциям: https://devcenter.heroku.com/articles/s3-upload-python, я сначала запрашиваю у бэкэнда подписанный запрос. (Я смог установить это в Python без проблем, используя boto3). Затем я использую подписанную информацию, чтобы попытаться загрузить фактический файл на S3. Но при этом я продолжаю получать 400 ошибок Bad Request.

Что также странно, так это то, что мне пришлось включить доступ publi c, чтобы получить ошибку 400, поскольку я имел обыкновение испытывать ошибки 403 Forbidden , даже с подписанными учетными данными.

Вот мой код:

const config = { headers: { 'Content-Type': 'application/json' } }
const file_name = file.name
const file_type = file.type
const body = JSON.stringify({ file_name, file_type });
axios.post('/api/triggers/create/video/sign_request', body, config)
.then(res => {
  let content = {}
  for (var key in res.data.data.fields) {
    content[key] = res.data.data.fields[key]
  }
  content['file'] = file
  const config = { headers: { 'Content-Type': file.type } }
  axios.put(res.data.data.url, content, config)
  //...
})

Я предпочитаю использовать топор ios, но я также попробовал следующий код, который использовался в уроке по Heroku выше. К сожалению, это дает те же результаты.

const file_name = file.name
const file_type = file.type
const body = JSON.stringify({ file_name, file_type });
axios.post('/api/triggers/create/video/sign_request', body, config)
.then(res => {
  var fd = new FormData()
  for (var key in res.data.data.fields) {
    fd.append(key, res.data.data.fields[key])
  }
  fd.append('file', file)
  var xhr = new XMLHttpRequest();
  xhr.open('POST', res.data.data.url, true);
  xhr.send(fd)
  //...
})

Учетные данные, используемые для подписания запроса, связаны с пользователем IAM, который имеет полный доступ к S3. enter image description here

Подписанный запрос, который я получаю от моего Django бэкэнда, выглядит следующим образом:

{
    "data": {
        "url": "https://my-bucket.s3.amazonaws.com/",
        "fields": {
            "acl": "public-read",
            "Content-Type": "video/mp4",
            "key": "funnycatisfunny.mp4",
            "AWSAccessKeyId": "BLABLABLAACCESSKEYBLABLABLA",
            "policy": "eyJleHBpcmF0aW9uIjogIjIwMjAtMDQtMDJUMTU6NDg6MTlaIiwgEtceteraEtCeterA",
            "signature": "S1GnAtuREWdleI4WXv5WHEBjc="
        }
    },
    "url": "https://my-bucket.s3.amazonaws.com/funnycatisfunny.mp4"
}

Раньше у меня возникали проблемы из-за CORS, но они исчезли после указания следующей конфигурации:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Я подумал, что, возможно, проблема в том, что в корзине S3 отсутствует политика, поэтому я определил одну:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:Put*",
            "Resource": "arn:aws:s3:::my-bucket/*"
        }
    ]
}

Это тоже ничего не изменило.

Может не оборачивайся вокруг этого. Любая помощь очень ценится.

ОБНОВЛЕНИЕ : Оказывается, я помещаю файл с неправильным URL-адресом, а именно с URL-адресом корзины, в то время как всегда следует ПОСТАВЛЯТЬ Bucketurl / Имя файла . Настройка позволила мне загрузить файл на S3. Однако, как только я снова блокирую доступ publi c, я получаю 403 Forbidden , как и раньше.

...