Browser-Side Amazon S3 Uploads, Using CORS
Today AWS added a really cool feature called S3 Cross-Origin Resource Sharing. With CORS, you can securely upload files directly into an S3 bucket, from the client-side, without using an intermediate proxy.
This is awesome for companies that upload tons of data into S3, why not use Amazon’s servers rather than your own?
As a test, I just finished porting Attachments.me’s uploading functionality over to CORS. Here’s what it involved:
1. Create a CORS Configuration Manifest
You need to create a CORS configuration manifest, for the bucket you wish to grant access to. Amongst other things, the manifest indicates:
- what domains are allowed to access the S3 bucket.
- the actions that can be taken (PUT, POST, GET, DELETE)
- choose the S3 option from your AWS Management Console.
- On the bucket you wish to grant CORS access to, click the properties option.
- note the option, Edit CORS Configuration
I created a configuration that looks something like this:
2. Create Signed POST Parameters
To upload to S3 from the client-side, you need to populate several special post parameters. Basically, you use your AWS credentials to securely sign a manifest. This manifest describes what actions an individual is allowed to perform on your S3 bucket.
There’s detailed documentation on this subject here
My manifest ended up looking something like this:
It’s worth noting that I created new, restricted, AWS credentials for signing this manifest.
3. Browser-Side Amazon S3 Uploads, Using CORS
Without further ado, here’s the code that I used for uploading via CORS. A few things to note:
- HTML 5’s FormData object is used to facilitate the multipart upload. This API allows us to track realtime upload progress.
- the special signed HTML POST parameters we created are added to the FormData object, using the append() method.
- This code is running in a Chrome Extension, some work would likely be needed to make it work on more browsers.
Not too painful! and pretty awesome:
- we get to upload using Amazon’s servers rather than our own.
- we can take advantage of HTML 5 technology to display realtime upload progress information.
Hope you’ve found this useful, if you have any questions don’t hesitate to tweet at me:
— Ben (@benjamincoe)