vendredi 1 avril 2016

Access Control Allow Origin Error in Ember/Rails file upload to AWS

I'm trying to setup a file upload functionality to my Ember frontend using the Rails backend to create the correct JSON for authentication with my S3 bucket.

I sticking as far as I can with the ember-uploader documentation , especially with the section "Rails Setup" and also this: EmberJs: Upload files directly to S3 with EmberJS and the ember-uploader addon.

I created my bucket and changed the CORS configuration as follows:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://ift.tt/1f8lKAh">
    <CORSRule>
        <AllowedOrigin>http://localhost:4200</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

(The Ember frontend uses port 4200)

I've got no error messages from the Ember and Rails servers. But the developer console shows:

XMLHttpRequest cannot load http://ift.tt/1q9qcKc. 
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:4200' is therefore not allowed access.

an the upload obviously doesn't occur.

My rails gallery controller:

class Api::V1::GalleryController < ApplicationController

  def sign
    @expires = 10.hours.from_now    
    render json: {             
      acl: 'public-read',      
      awsaccesskeyid: ENV['AWS_ACCESS_KEY_ID'],
      bucket: ENV['AWS_BUCKET'], 
      @expires = 10.hours.from_now    
      render json: {             
      acl: 'public-read',      
      awsaccesskeyid: ENV['AWS_ACCESS_KEY_ID'],
      bucket: ENV['AWS_BUCKET'],      
      expires: @expires,       
      region: 'eu-west-1',     
      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'),
        #OpenSSL::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: ENV['AWS_BUCKET'] },  
          { 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

Please note that I configured the bucket to be in central Europe since the AWS bucket was also created for the same zone (Frankfurt). Also I set up correctly my environment variables in Rails and checked if they show up in the console.

I don't know what I'm missing here since none of the tutorials I am following mentions how to attach the Access Control Allow Origin Header to the request and where.




Aucun commentaire:

Enregistrer un commentaire