File Upload to S3 via Browser
In this blog, we will discuss how we can upload files directly to S3 from a browser, rather than uploading a file first to your servers and then to S3.
Uploading files directly to S3 basically gives us two advantages:
- You don’t have to build functionality in your system to upload files
- Reduces the load on your servers.
The picture below explains what we want to achieve in a very simple way.
AWS provides the ability to upload files directly to S3 via a POST endpoint.
There are two ways with which you can authenticate who can upload the file to S3:
• AWS IAM Temporary Access Credentials
• Pre-Signed POST policy.
We need to make sure that these temporary credentials or pre-signed policies are only available to authorized users.
In our case, this authorization was done by our Rest API. An endpoint only available to authorized users was used to provide a Pre-Signed POST policy. But this can be done in any other way that fits your use case, the important point is to make sure that only authorized users have access to these temporary credentials or to the pre-signed policy.
AWS IAM Temporary Access Credentials (not recommended):
In this case, the API gets the Temporary Access Credentials from the IAM role assigned to the server.
The IAM role should have access to the S3 bucket you want to upload the file to.
Below is an example code of how you can get the temporary credential using the servers IAM role.
Pre-Signed POST policy.
In this case, rather than using the temporary credentials you use a pre-signed POST policy. This policy is then used to send the upload request to S3 directly via an HTML form.
So, rather than returning the credentials your API will actually return a pre-signed policy document looking something like below.
I like the Pre–Signed Policy a lot more as it gives you a lot more control to restrict the permissions you are giving to the end user. As you see, you can configure the expiration time, the exact bucket they can upload to, the prefix, the type of file and the size of the file.
This pre-signed policy is then used in a form with a submit button to upload the file. Something like below.
One of the most important parameters of the form above is the X-Amz-signature which is used by AWS to authenticate the file upload request, so let see how to create that signature below.
The signature used to authenticate the request is called AWS Signature Version 4
Aws explains in detail the way to create this signature here
Below is a sample Java Code of how we create the signature.
So now you know how you can create a pre-signed policy and then use it to upload a file.
I hope this helps, please find below more links to dig deeper into it.
PS: Many thanks to Maxime Nay for doing the proof-reading.