Briefly, What is CORS?
Cross-Origin Resource Sharing (CORS) is a mechanism through which a web application (in this example, that’s the S3 bucket) uses special HTTP headers to inform a browser if a user has permission to access content from another web application.
If this is a new concept to you dear reader, please head over to MDN where you can find an excellent article on the subject.
S3, CloudFront and CORS
The reason I decided to write this post, is because it took me quite a bit of reading through the AWS documentation as well as a decent amount of trial and error to get the settings right.
So, dear future me (and anyone else facing this predicament), here is the recipe:
Step 1: Configure S3
First we need to configure the S3 to allow CORS when accessing content stored on the bucket. That is, when we are accessing files directly, without a CDN.
Head over to the S3 Management console and switch to the Permissions tab of the bucket. Then select the CORS configuration section.
The CORS configuration editor gives us the ability to compose the CORS configuration for the entire bucket. For the sake of simplicity, we are going to define a single rule allowing access from any origin. (Of course, you will consider creating a separate rule for each origin your application will use before going in production).
<?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <MaxAgeSeconds>3000</MaxAgeSeconds> </CORSRule> </CORSConfiguration>
The syntax for a CORS Configuration can be found in the AWS documentation.
Step 2: Configure CloudFront
Finally, we need to configure CloudFront so that it will correctly cache the headers being passed between our client web application and S3. This is the tricky part which took me quite some time to figure out.
Open the properties of the CloudFront Distribution which needs to be configured and switch to the Behaviors tab.
Next, click Edit and ensure the following are enabled:
- Allowed HTTP Methods should include OPTIONS
- Cached HTTP Methods should include OPTIONS
- Cache Based on Selected Request Header should be set to a Whitelist with the following setup:
The choice of headers here is not arbitrary. Actually, AWS has a document on the topic explaining the possible options.
- Apply the changes. 👀
CloudFront may need several minutes to propagate the new settings.