I've been having an issue across many of my sites that rely on S3 as an origin for Cloudfront. However, I'm having issues with allowing multiple domains (instead of a global *
allowed).
I have followed the documentation here (first config). And found a few other random SO or forum answers here and there (second config)
Any help is appreciated.
I have setup CORS Rules that look like both of the following:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>https://example.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>http://example.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>https://staging.example.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>http://example.dev</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
AND
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>https://example.com</AllowedOrigin>
<AllowedOrigin>http://example.com</AllowedOrigin>
<AllowedOrigin>https://staging.example.com</AllowedOrigin>
<AllowedOrigin>http://example.dev</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
I keep getting the font origin error on all sites except https://example.com
:
Font from origin 'http://CLOUDFRONTURL' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example.dev' is therefore not allowed access.
AND
Font from origin 'http://CLOUDFRONTURL' has been blocked from loading by Cross-Origin Resource Sharing policy: The 'Access-Control-Allow-Origin' header has a value 'https://example.com' that is not equal to the supplied origin. Origin 'http://example.dev' is therefore not allowed access.
To initiate a cross-origin request, a browser sends the request with an Origin: <domain> HTTP header, where <domain> is the domain that served the page. In response, the server sends Access-Control-Allow-Origin: <domain> , where <domain> is either a list of specific domains or a wildcard to allow all domains.
Sign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/ . In the Buckets list, choose the name of the bucket that you want to create a bucket policy for. Choose Permissions. In the Cross-origin resource sharing (CORS) section, choose Edit.
Cross-origin resource sharing (CORS) defines a way for client web applications that are loaded in one domain to interact with resources in a different domain. With CORS support, you can build rich client-side web applications with Amazon S3 and selectively allow cross-origin access to your Amazon S3 resources.
You have to either load your image with the crossOrigin attribute set to 'anonymous' directly in your document, or you can try useCORS h2c option. allowTaint option does just say that you don't care if it taints the canvas or not.
dev.mydomain.com
) and domain B (e.g. www.mydomain.com
).cdn.mydomain.com
which is on CloudFront and points to a private S3 bucket./fonts/myfont.woff
, which needs CORS, per MDN) are accessible when you request them from www.mydomain.com
via https://cdn.mydomain.com/fonts/myfont.woff
. (See my answer here on how to set it up, up to this point.)cdn.mydomain.com/fonts/myfont.woff
only when the page that requests it (i.e. Origin
header) is either dev.mydomain.com
or www.mydomain.com
.junk-cheap.com
loads your font file on this page (via your CDN URL), to save on his own bandwidth/hosting cost; not to mention phishing and such risks!By default CloudFront caches the response for any incoming request. That's the whole point of CDN.
However, the first time (after an Invalidation) that a request comes from any of the two domains for a certain file (say /fonts/myfont.woff
), CloudFront caches the response for this file as { "/fonts/myfont.woff": "<this response object with headers>"}
. So the cache-key is by default almost only the path.
Now, when a request from domain B comes for the same file, the "allowed domain" of the cached response of the object is for domain A, and this mismatch results in a CORS error.
One simple solution would be telling CloudFront to incorporate Origin
into the cache key. So, in the above example the cache would be like { ["/fonts/myfont.woff", "Origin: www.mydomain.com"]: <response for www.mydomain.com only>, ... }
.
You can accomplish this by creating a new Cache Policy that takes in the Origin
header:
and then set it up on your Behavior.
Now, invalidate the distribution and try again! It should work. :)
Good luck!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With