2017-12-10 10 views
0

を失敗のContent-Typeポリシー私は、次の403エラーを取得してアップロードS3への直接のコンテンツタイプを指定しようとしています:AWS S3 - ルビー - Presigned POST:

Invalid according to Policy: Policy Condition failed: ["starts-with", "$Content-Type", ""]

私はすべてに入れているIここにある他の投稿から無駄に見つけることができます。私のコード:

設定/初期化子/ aws.rb

Aws.config.update({ 
    region: 'us-east-1', 
    credentials: Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY']), 
}) 

S3_BUCKET_NAME = Aws::S3::Resource.new.bucket(ENV['S3_BUCKET_NAME']) 

doc_uploads_controller.rb

before_action :set_s3_direct_post 
private 
def set_s3_direct_post 
    @s3_direct_post = S3_BUCKET_NAME.presigned_post(key: "my_path/${filename}", success_action_status: '201', acl: 'authenticated-read', server_side_encryption: 'AES256', content_type_starts_with: '') 
end 

new.html.erb

<%= form_for(@doc_upload, url: new_doc_upload_path, html: { class: "directUpload" }, data: { 'form-data' => (@s3_direct_post.fields), 'url' => @s3_direct_post.url, 'host' => URI.parse(@s3_direct_post.url).host }) do |f| %> 
    <%= render 'errors', f: f %> 
    <%= hidden_field_tag "Content-Type", "" %> 
    <div class="row"> 
    <span class="btn btn-success fileinput-button"> 
     <span>Select File</span> 
     <!-- The file input field used as target for the file upload widget --> 
     <input id="doc_upload_file_url" type="file" name="doc_upload[file_url]"> 
    </span> 
    <!-- The container for the uploaded files --> 
    <div id="files" class="files"></div> 
    <div id="progress" class="progress"> 
     <div class="progress-bar progress-bar-success"></div> 
    </div> 
    </div> 
    <div class="row"> 
    <p><%= f.button "Save", id: 'doc-upload-submit', disabled: true, data: {disable_with: "<i class='fa fa-spinner fa-spin'></i> Saving..."}, class: "btn btn-form btn-warning" %></p> 
    <p><%= link_to 'Cancel', doc_uploads_path, id: 'cancel-link' %></p> 
    </div> 
<% end %> 

doc_uploads.js.coffee

$(document).on 'turbolinks:load', -> 
    $ -> 
    'use strict' 
    url = $('.directUpload').find("input:file").parents('form:first').data('url') 
    formdata = $('.directUpload').find("input:file").parents('form:first').data('form-data') 
    uploadButton = $('<button/>') 
     .addClass('btn btn-default btn-upload') 
     .prop('type', 'button') 
     .prop('disabled', true) 
     .text('Processing...') 
     .on('click', -> 
     $('#cancel-link').hide() 
     $this = $(this) 
     data = $this.data() 
     $this.off('click').text('Abort').on('click', -> 
      $this.remove() 
      data.abort() 
      $('#cancel-link').show() 
     ) 
     data.submit().always(-> 
      $this.remove() 
     ) 
    ) 
    $('#doc_upload_file_url').fileupload({ 
     url: url, 
     type: 'POST', 
     autoUpload: false, 
     formData: formdata, 
     paramName: 'file', 
     dataType: 'XML', 
     replaceFileInput: false, 
     maxNumberOfFiles: 1, 
     acceptFileTypes: /(\.|\/)(jpe?g|jpg|png|pdf|doc|docx|xls|xlsx)$/i, 
     maxFileSize: 104857600, 
     uploadTemplateId: null, 
     downloadTemplateId: null, 
     dropZone: null 
     }).on('fileuploadadd', (e, data) -> 
     $('#filename').remove() 
     data.context = $('<div/>').prop('id', 'filename').appendTo('#files') 
     $.each(data.files, (index, file) -> 
      node = $('<p/>').append($('<span/>').text(file.name)) 
      node.appendTo(data.context) 
      if (!index) 
      $('#filename').append(uploadButton.clone(true).data(data)) 
     ) 
    ).on('fileuploadprocessalways', (e, data) -> 
     index = data.index 
     file = data.files[index] 
     $('#Content-Type').attr('value',file.type) 
     node = $(data.context.children()[index]) 
     if (file.error) 
      node.append('<br>').append($('<span class="text-danger"/>').text(file.error)) 
     if (index + 1 == data.files.length) 
      data.context.find('button').text('Upload').prop('disabled', !!data.files.error) 
    ).on('fileuploadprogressall', (e, data) -> 
     progress = parseInt(data.loaded/data.total * 100, 10) 
     $('#progress .progress-bar').css('width',progress + '%') 
    ).on('fileuploaddone', (e, data) -> 
     form = $('.directUpload').find("input:file") 
     key = $(data.jqXHR.responseXML).find("Key").text() 
     input = $("<input />", { type:'hidden', name: form.attr('name'), value: key }) 
     form.append(input) 
     $('#progress .progress-bar').css('background', 'green').text("Upload Complete") 
     $('#doc-upload-submit').prop('disabled', false) 
     $('#doc-upload-submit').trigger('click') 
     , 
    ).on('fileuploadfail', (e, data) -> 
     message = $(data.jqXHR.responseXML).find("Message").text() 
     $.each(data.files, (index) -> 
      error = $('<span class="text-danger"/>').text('File upload failed.') 
      $(data.context.children()[index]).append('<br>').append(error) 
     ) 
    ).prop('disabled', !$.support.fileInput).parent().addClass($.support.fileInput ? undefined : 'disabled') 

予約済み投稿からcontent_type_starts_with:の設定を削除すると、すべてがうまく動作し、S3のコンテンツタイプの設定を引いた値になります。 Content-Typeを送信する前にフォームに正しく設定していませんか? 助けてください!

更新:次のように非表示のフィールドの更新を置き換えようとしましたが、403応答が維持されています。

{key: "uploads/1/${filename}", success_action_status: "201", acl: "authenticated-read", x-amz-server-side-encryption: "AES256", policy: "eyJleHBpcmF0aW9uIjoiMjAxNy0xMi0xMVQwNDo1Mzo1NFoiLC…seyJ4LWFtei1kYXRlIjoiMjAxNzEyMTFUMDM1MzU0WiJ9XX0=", …} 
    Content-Type: "application/pdf" 
    acl: "authenticated-read" 
    key: "my_path/${filename}" 
    policy: "eyJleHBpcmF0aW9uIjoiMjAxNy0xMi0xMVQwNDo1Mzo1NFoiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJlZy1zdGFnaW5nLXVwbG9hZHMifSxbInN0YXJ0cy13aXRoIiwiJGtleSIsInVwbG9hZHMvMS8iXSx7InN1Y2Nlc3NfYWN0aW9uX3N0YXR1cyI6IjIwMSJ9LHsiYWNsIjoiYXV0aGVudGljYXRlZC1yZWFkIn0seyJ4LWFtei1zZXJ2ZXItc2lkZS1lbmNyeXB0aW9uIjoiQUVTMjU2In0sWyJzdGFydHMtd2l0aCIsIiRDb250ZW50LVR5cGUiLCIiXSx7IngtYW16LWNyZWRlbnRpYWwiOiJBS0lBSURKNE1LRjdMTlA3RDZLUS8yMDE3MTIxMS91cy1lYXN0LTEvczMvYXdzNF9yZXF1ZXN0In0seyJ4LWFtei1hbGdvcml0aG0iOiJBV1M0LUhNQUMtU0hBMjU2In0seyJ4LWFtei1kYXRlIjoiMjAxNzEyMTFUMDM1MzU0WiJ9XX0=" 
    success_action_status: "201" 
    x-amz-algorithm: "AWS4-HMAC-SHA256" 
    x-amz-credential: "[redacted]" 
    x-amz-date: "20171211T035354Z" 
    x-amz-server-side-encryption: "AES256" 
    x-amz-signature:"[redacted]" 
    __proto__:Object 

答えて

0

あなたが代わりに隠しフィールドでの、FORMDATA上のContent-Typeを設定する必要があります。

formdata["Content-Type"] = file.type 
console.log(formdata) 
data.formData = formdata 
console.log(data.formData) 

コンソールは、結果data.formDataとして示しています。

の代わりに:

$('#Content-Type').attr('value',file.type)

試してみてください。

formdata["Content-Type"] = file.type 
data.formData = formdata 

これは私のために働いたが、私は一度に一つのファイルをアップロードしました。複数のファイルをアップロードしているので、コンテンツタイプが異なる場合、これはうまくいかないかもしれませんが、試してみる価値があります。


アップデート:ここに私のために働いたコードだが、それはS3に直接autoUploadん覚えておいて、それはあなたがやっているものとは異なること、それが役に立てば幸いかもしれません。

# @s3ResumeFields came from @s3_direct_post.fields 
formData = @s3ResumeFields 

resumeInput.fileupload 
    fileInput: resumeInput, 
    url: @s3ResumeUrl, # this came from @s3_direct_post.url 
    type: 'POST', 
    autoUpload: true, 
    formData: formData, 
    paramName: 'file', 
    dataType: 'XML', 
    replaceFileInput: false 
    add: (e, data) -> 
     formData["Content-Type"] = data.files[0].type 
     data.formData = formData 
     data.submit() 
    progressall: (e, data) -> 
     # unrelated UI updates to show progress 
    start: (e) -> 
     # unrelated UI updates to show progress 
    done: (e, data) -> 
     # unrelated UI updates to notify that the upload completed 

    fail: (e, data) -> 
     # unrelated UI updates to show upload failed 
+0

これは役に立たないと試しましたが、403エラーが残ります。最新の記事を参照してください。 – CChandler81

+0

私は現時点で1つのファイルでこれを試しているに過ぎないと言いました。ありがとう。 – CChandler81

+0

'fileuploadadd'のコンテンツタイプを設定してみることができます –

関連する問題