clock menu more-arrow no yes mobile

Filed under:

The missing guide to S3 uploads with EvaporateJS + Ruby on Rails

EvaporateJS is a full-featured S3 file uploader with a simple headless API that provides chunked and resumable uploads, as well as transfer acceleration capabilities. If you’re looking for a robust yet unopinionated direct-to-S3 file uploader and you can live without a stylish project website, Evaporate fits the bill. Just be warned – the documentation and related code samples are a bit disorganized, making this tool appear harder to use than it really is. Here’s a quick-start guide that should get you up and running.

Step 1: Configure CORS for your S3 bucket

First you’ll need to configure your S3 bucket to accept chunked uploads. Go into the AWS console and access Amazon S3 > your-bucket > Permissions > CORS Configuration, and enter the following:

The PUT and ETag options are required for chunked uploading. Note that AllowedOrigin:* will allow any domain to submit upload requests to your S3 bucket, so you should limit that to your specific domain(s) in your production app. For advanced configuration, see the official docs and the equally helpful FineUploader docs on this topic.

Step 2: Configure Rails with a signing service

All uploads sent to S3 need to be authorized using your AWS secret key. However, secret keys should never appear in public-facing code, so Evaporate (and similar tools like FineUploader) will generate an upload policy and send that to your application server for signing. A signature is just a SHA hash derived from the proposed upload policy combined with your AWS secret key. Once Evaporate has a signed policy, it can start uploading a file directly from the browser.

To establish a signing service in Rails, define a route for get “/uploads/auth”, and point it at the following controller action:

Note that this implements an AWS v4 signature, which Evaporate uses by default. The Evaporate signing examples include both v4 and v2 signature methods for many different languages – be sure to select the v4 method for your app.

Step 3: Client-side JavaScript

Now all that’s left is to configure Evaporate and start uploading files. To upload from a browser, the first thing you’ll need to do is add some missing crypto functions. You’ll need MD5 and SHA256, which can be obtained from the packages spark-md5 (supports ArrayBuffer) and js-sha256. If you’re uploading from a Node environment, you can use Node’s built-in crypto libraries.

Create an Evaporate instance with the path to your application’s signature service, your AWS public key (or, “Access Key”), the name of your bucket, and references to your hashing functions:

That’s it, Evaporate should be all set up. Now just add a file input field to your app and try uploading any file that you select with it:

Happy uploading!