benefitcloud / ember-uploader

An Ember library for uploading files
MIT License
346 stars 97 forks source link

400BadRequest on upload #158

Open BobrImperator opened 7 years ago

BobrImperator commented 7 years ago

Hello, I am getting 400Bad Request error on POST method after receiving a upload URL from Rails Api.

My ember client is pretty much copy-pasted from README, as is rails controller from wiki.

Rails controller ` class SignController < ApplicationController

     def sign
       @expires = 10.hours.from_now.utc.iso8601
       render json: {
      acl: 'public-read',
      awsaccesskeyid: ENV['AWS_ACCESS_KEY_ID'],
      bucket: 'shrinked-in',
      expires: @expires,
      key: "uploads/#{params[:name]}",
      policy: policy,
      signature: signature,
      success_action_status: '201',
      'Content-Type' => params[:type],
      'Cache-Control' => 'max-age=630720000, public'
      }, status: :ok
    end

    def signature
      Base64.strict_encode64(
      OpenSSL::HMAC.digest(
        OpenSSL::Digest::Digest.new('sha1'),
        ENV['AWS_SECRET_ACCESS_KEY'],
        policy({ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'] })
        )
      )
    end

    def policy(options = {})
      Base64.strict_encode64({
        expiration: @expires,
        conditions: [
          { bucket: 'shrinked-in' },
          { acl: 'public-read' },
          { expires: @expires },
          { success_action_status: '201' },
          [ 'starts-with', '$key', '' ],
          [ 'starts-with', '$Content-Type', '' ],
          [ 'starts-with', '$Cache-Control', '' ],
          [ 'content-length-range', 0, 524288000 ]
          ]
        }.to_json
      )

end end` Here's also a snippet from rails console

Started GET "/sign?name=local.png&type=image%2Fpng&size=14968" for 127.0.0.1 at 2017-07-14 23:18:23 +0200 Processing by SignController#sign as HTML Parameters: {"name"=>"local.png", "type"=>"image/png", "size"=>"14968", "sign"=>{}} ../app/controllers/sign_controller.rb:22: warning: constant OpenSSL::Digest::Digest is deprecated [active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash (0.18ms) Completed 200 OK in 4ms (Views: 2.4ms | ActiveRecord: 0.0ms)

Ember component

`import Ember from 'ember'; export default EmberUploader.FileField.extend({ signingUrl: 'http://localhost:3000/sign',

filesDidChange (files) { const uploader = EmberUploader.S3Uploader.create({ signingUrl: this.get('signingUrl') });

uploader.on('didUpload', response => {

  let uploadedUrl = $(response).find('Location')[0].textContent;

  uploadedUrl = decodeURIComponent(uploadedUrl);
});

if (!Ember.isEmpty(files)) {

  uploader.upload(files[0]);
}

} });`

I couldn't find anything related to my problem for 2days, so I decided to make an issue.

digitaltoad commented 7 years ago

Instead of using a custom signing method as I have detailed previously, use the aws-sdk-ruby to generate a pre-signed url for uploading.

TristanToye commented 6 years ago

Struggling to replace the example with a pre-signed url from the sdk. Can't seem to get the credentials encrypted.

Trying to use Aws::S3::PresignedPost but unclear on how to configure it the same way as the example.