URL-адреса с указанием S3: недопустимы в соответствии с политикой: условие политики не выполнено success_action_status

#ruby-on-rails #ruby #amazon-web-services #amazon-s3 #aws-sdk

#ruby-on-rails #рубиновый #amazon-web-services #amazon-s3 #aws-sdk

Вопрос:

Я пытаюсь выдавать предварительно подписанные URL-адреса через свой сервер, а затем загружать их через javascript в браузере. Все работает, когда я оставляю поле :success_action_status, но я хочу установить для него значение 201, чтобы вернуть XML после загрузки.

На сервере:

 s3_bucket = Aws::S3::Resource.new.bucket(UploadFile::DECK_BUCKET)
presigned_url = s3_bucket.presigned_post(
  :key => @upload_file.key,
  :content_length_range => 1..(10*1024),
  :success_action_status => '201',
  :signature_expiration => expire
)

data = { url: presigned_url.url, url_fields: presigned_url.fields }
render json: data, status: :ok
 

На клиенте:

 this.file.change(function() {
  var formData = new FormData();
  formData.append("key", that.fields.key);
  formData.append("X-Amz-Credential", that.fields['x-amz-credential']);
  formData.append("X-Amz-Algorithm", "AWS4-HMAC-SHA256");
  formData.append("X-Amz-Date", that.fields['x-amz-date']);
  formData.append("Policy", that.fields.policy);
  formData.append("X-Amz-Signature", that.fields['x-amz-signature']);
  formData.append("file", that.file[0].files[0]);
  formData.append("success_action_status", that.fields['success_action_status']);
  that.$http.post(that.url, formData).then(function(response) {
    console.log("yup")
    console.log(response)
  }, function(response) {
    console.log("nope")
    console.log(response)
  });
 

Опять же, это работает, когда я оставляю success_action_status поле in presigned_post . Но когда я этого не делаю, я получаю:

 Invalid according to Policy: Policy Condition failed: ["eq", "$success_action_status", "201"]
 

Кто-нибудь знает, что происходит?? Спасибо!

РЕШЕНИЕ:

formData.append("file", that.file[0].files[0]); должно быть последнее, что добавляется к форме.

Ответ №1:

Похоже, в документации нет ничего конкретного относительно того, почему это не сработает.

Обновить

Попробуйте поместить success_action_status поле перед полем файла

 this.file.change(function() {
  var formData = new FormData();
  formData.append("key", that.fields.key);
  formData.append("X-Amz-Credential", that.fields['x-amz-credential']);
  formData.append("X-Amz-Algorithm", "AWS4-HMAC-SHA256");
  formData.append("X-Amz-Date", that.fields['x-amz-date']);
  formData.append("Policy", that.fields.policy);
  formData.append("X-Amz-Signature", that.fields['x-amz-signature']);
  formData.append("success_action_status", that.fields['success_action_status']);
  formData.append("file", that.file[0].files[0]);
  that.$http.post(that.url, formData).then(function(response) {
    console.log("yup")
    console.log(response)
  }, function(response) {
    console.log("nope")
    console.log(response)
  });
 

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

1. Причина, по которой это не сработает, заключается именно в том, что formData.append("success_action_status",... отсутствует. Политика определяет и ограничивает то, что должна содержать форма, поэтому без этого форма действительно «недействительна в соответствии с политикой».

2. Я добавил formData.append("success_action_status", '201') и все ту же ошибку. Я попробовал 201 в целочисленной и строковой форме. Если я использую 201 как целое число в коде ruby, я получаю сообщение об ошибке.

3. @Michael-sqlbot можете ли вы дать несколько советов здесь?

4. @frausto formData.append("file", ... должно быть последним , добавленным к форме. Добавьте success_action_status выше, а не ниже.

5. @Michael-sqlbot вот и все! Спасибо за ответ!