Borislav Hadzhiev
Thu Sep 23 2021·3 min read
Photo by Michael L
CORS is a mechanism that allows a server to use a combination of HTTP headers to indicate from which domains, other than its own, it receives requests.
By default servers only take requests made from applications hosted on the same domain.
All S3 buckets are hosted on the https://amazonaws.com
domain, which is
different from where we host our client applications, so we have to set up
CORS.
To configure an S3 bucket to allow cross-origin requests, you have to:
Permissions
tabCross-origin resource sharing (CORS)
section and click
on the Edit
button[ { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "GET", "HEAD", "PUT", "POST" ], "AllowedOrigins": [ "*" ], "MaxAgeSeconds": 3000 } ]
The CORS configuration consists of the following properties:
AllowedHeaders
- which headers are allowed to be sent in a preflight
(OPTIONS
) request.
In the example above we've used the *
wildcard character to specify that all
headers are allowed in a preflight request.
AllowedMethods
- which HTTP methods the specified origins are allowed to
perform on the S3 bucket.
You might have to tweak this value, e.g. if your frontend only needs to make
GET
requests to the S3 bucket, you can remove the PUT
and POST
methods.
Conversely, if you need to make DELETE
requests to the S3 bucket, add the
method.
AllowedOrigins
- which origins (domains) are allowed to make requests to
the S3 bucket.
In our case we've set the value to a wildcard, meaning all domains. However,
it's a best practice to only allow requests from known origins. If you own a
domain https://example.com
this is what you would specify here.
You can pass multiple origins in the array, however note that each origin can
contain a maximum of 1 wildcard character. For example specifying an origin of
https://*.example.com
, would enable requests to your S3 bucket from all
subdomains, e.g. - https://wwww.example.com
and https://blog.example.com
.
MaxAgeSeconds
- this is an optional element. It defines the time in
seconds that the browser caches an S3 response to a preflight OPTIONS
request for the specified resource.
If the response is cached, the browser doesn't have to send OPTIONS
requests
for the same resource over and over.
We can provide multiple rule objects in a CORS configuration, in fact up to 100 rules can be defined in a single CORS configuration.
Let's look at an example with 2 rules. The configuration allows PUT
, POST
and DELETE
requests from a specific origin and GET
requests from all
origins.
[ { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "POST", "PUT", "DELETE" ], "AllowedOrigins": [ "https://www.example.com" ] }, { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "GET", "HEAD" ], "AllowedOrigins": [ "*" ], "MaxAgeSeconds": 3000 } ]
In the CORS configuration above, we've specified that all origins can make GET
requests to our S3 bucket.
However only the https://www.example.com
origin can perform POST
, PUT
and
DELETE
operations on the bucket.
AllowedMethods
and AllowedOrigins
that your application needs to function properly.