AWS S3 – Pre-signed URL uploads

RUBY (create a pre-signed & public url from server side)

s3 = Aws::S3::Resource.new
obj = s3.bucket('bucket-name').object('files/hello.text')

put_url = obj.presigned_url(:put, acl: 'public-read', expires_in: 3600 * 24, content_type: 'multipart/form-data')
#=> "https://bucket-name.s3.amazonaws.com/filesp/hello.text?X-Amz-..."

obj.public_url
#=> "https://bucket-name.s3.amazonaws.com/files/hello.text"

You can fetch pre-signed URL from server side either directly while landing on the page or via AJAX. Preferred method is do a AJAX to server side with the param (filename) and in the server generate a pre-signed url using file name and time-stamp. 

JAVASCRIPT (Trigger a PUT call to AWS S3 using pre-signed url)

$.ajax( {
    url: url, //presinged-url which you get from server side
    type: 'PUT',
    data: file,
    processData: false,
    contentType: false,
    headers: {'Content-Type': 'multipart/form-data'},
    success: function(){
        console.log('Image successfully uploaded. Now the object (image/pdf/text/whatever-it-is now can be downloaded using public url received from server side');
    }
    error: function(){
        console.log('Something went wrong');
    }
});

ADD CORS ON AWS S3 (do this only for a particular bucket, avoid doing it globally)

    
 <CORSConfiguration>
 <CORSRule>
 <AllowedOrigin>*.mydomain.com</AllowedOrigin>
 <AllowedMethod>PUT</AllowedMethod>
 <MaxAgeSeconds>3000</MaxAgeSeconds>
 <AllowedHeader>Content-*</AllowedHeader>
 <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>