AWS Cloudfront CORS headers without S3 bucket - amazon-web-services

I'm using CloudFront CDN to simply cache my static contents in "Origin Pull" mode. The CloudFront origin is my website.
However, I've encountered a CORS problem. My browser doesn't let my web pages load my fonts files and SVGs from CloudFront.
After googling this matter a bit, I noticed that all blogs/tutorials explain how to enable CORS on an S3 bucket used as the origin for CloudFront, and letting CloudFront forward the Access-Control-Allow-XXX headers from S3 to the client.
I don't need an S3 bucket and would like to keep it that way for the sake of simplicity, if possible.
Is it possible to enable CORS on CloudFront? Even a quick and dirty solution, such as setting the access control header on all responses would be good enough.

Following up the comment above, CORS is a request made FROM a domain different of the TO domain. The key part to avoid this, is in the server which returns your requests return the header allowing cross origin requests.
Your fonts, which should be your website's assets, should be kept in the same server as your website, therefore CORS should not be an issue.

Related

Cloudfront removes Set-Cookie header from response to viewer

I have a NextJs application running in an AWS EC2 instance. The application includes static pages and APIs for login. Now, I am trying to setup AWS Cloudfront distribution. However, I am facing a challenge because CloudFront removes the Set-Cookie header from the login API Response and it's breaking the login functionality.
Below is the reference of the cache behavior setup in which I have disabled caching for the /api/* path.
Precedence
Path pattern
Cache policy name
0
/api/*
Managed-CachingDisabled
1
Default (*)
Managed-CachingOptimized
After referring AWS docs https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Cookies.html, I have noticed that it's possible to forward cookies from viewer to origin.
But, it's still not clear to me,
How to forward the Set-Cookie header from the origin response to viewer.
Why CloudFront removes the Set-Cookie header for the path /api/* in which caching has been disabled.
Appreciate any help on this. Thanks.

How to enable browser cache in AWS cloudfront

I have configured my cloudfront distribution to use the managed cache policy, however all tools (like google pagespeed, cache checkers etc) are not detecting any caching.
Neither is the browser detecting any cache related header.
What am I missing here?
sample CDN url: https://cdn.thekiwi.app/images/skills/SubCategories/81/desktop_b/81.png
I think you misunderstood how Cloudfront cache works.
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-the-cache-key.html
Cloudfront is the CDN that caches the resources on Cloudfront edge servers. Every time your users want to access your application's resources, either of the following 2 scenarios happens:
Cache hit: the resource is cached in Cloudfront servers and returned to your users without requesting your app's origin server
Cache miss: the resource is not cached and a request is sent to your app's origin server to retrieve. Then based on the cache policy you define in your Cloudfront distribution, the resource might or might not be cached in Cloudfront servers.
The cache policy you defined in your Cloudfront server tells Cloudfront when and how long to cache the resource.
Tools like Google pagespeed do not check for CDN cache, it checks for browser cache, which works based on the HTTP response headers such as Cache-Control
In order to set the Cache-Control value, you can either
(1) Write a Cloudfront functions to instruct Cloudfront to insert the header before returning responses to your users
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/example-function-add-cache-control-header.html
or
(2) Update your app's origin server to add the Cache-Control header for your resources.

AWS S3 images served only via HTTP, but Chrome upgrades to HTTPS

I am unable to make S3 images hosting to work over HTTPS. I read that "Amazon S3 website endpoints do not support HTTPS." - docs
I'm fine with hosting my images over HTTP, however, when I put the following tag in HTML:
<img src="http://MY-BUCKET-NAME.s3-website.eu-central-1.amazonaws.com/images/51612809-741c-40c7-8c29-7b332be709d7.jpg">
Chrome requests
https://MY-BUCKET-NAME.s3-website.eu-central-1.amazonaws.com/images/c1612a09-741c-40c6-8c29-7b332be709d7.jpg
(notice http became https), which results in ERR_CONECTION_TIMED_OUT.
How to make it work?
As we discussed in the comments, Chrome doesn't like mixed content anymore, i.e. it won't let you embed http content on a website that's served via https.
Now there are multiple options to make this work:
Downgrade the main website to http (don't do this, it's a terrible idea)
Make the bucket or at least the objects that you embed publicly readable in S3 and use the native https endpoint that S3 offers. It will look something like this:
https://<bucketname>.s3.<region>.amazonaws.com/<object-key>.jpg
This has essentially the same costs associated with it as your current solution. You might need to do some annoying CORS stuff though.
Set up a CloudFront distribution in front of your bucket and configure it to serve content from S3. You can use an Origin Access Identity to secure the communication between CloudFront and S3 and even customize TLS-configurations in CloudFront. This will give you caching closer to your users but comes with extra costs.

Aws S3 redirection rules issue for cloudfront https requests

We have an aws s3 bucket that hosts our dynamic images, which will be fetched by web and mobile apps through https and with different sizes (url/width x height/image_name) i.e. http://test.s3.com/200x300/image.png).
For this we did two things:
1- Realtime resizing: I have a redirection rule in my s3 bucket to redirect 404 errors requesting non-existing image sizes to an API gateway that calls a Lambda function. The lambda function fetches the original image and resizes it and places it in a folder in the bucket matching the requested size.
We followed the steps in this articles:
https://aws.amazon.com/blogs/compute/resize-images-on-the-fly-with-amazon-s3-aws-lambda-and-amazon-api-gateway/
2- HTTPS: I created a cloudfront distribution with an SSL certificate and its origin is the s3 static website endpoint
Problem: Requesting an image from s3 using the cloudfront https domain always causes an 404 error which gets redriected by my redirection rule the API gateway, even if this specific image size already exists.
I tried to debug this issue with no luck. I examined the requests and from what I see things should work normally.
I'd appreciate a hint on what to do to better debug this issue (and what kind of logs I need to provide here).
Thanks
Sary
This solution relies on S3 generating HTTP redirects for missing objects, to redirect the browser to API Gateway to resize the object... and save it at the original URL.
The problem is two-fold:
S3 generated redirects don't include any Cache-Control headers, and
CloudFront's default behavior when Cache-Control is absent in a response is to cache the response internally for the value of a timer called Default TTL, which by default is set to 86400 seconds (24 hours).
The problem this causes is that CloudFront will remember the original redirect and send the browser to it, again and again, even though the object is now present.
Selecting Customize instead of Use Origin Cache Headers for "Object caching" and then setting Default TTL to 0 (all in the CloudFront Cache Behavior settings) will resolve the issue, because it configures CloudFront not to cache responses where the origin didn't include any relevant Cache-Control headers.
For more background:
What is Cloudfront Minimum TTL for? explains the Minimum/Default/Maximum TTL timers and how/when they apply.
Setting "Object Caching" on CloudFront explains the confusing UI labeling of these options, which is likely a holdover from a time before all three timers were configurable.

Can I upload to CloudFront directly from the browser?

Now that CloudFront supports POST requests, is it possible to do browser-based uploads directly to CloudFront?
In theory, yes. However, there are very serious issues with support for anything but the most simple upload requests from a browser. For example, support for uploads to S3 via CloudFront using the multipart upload API is not possible due to the fact that CloudFront rips off the Authorization header from all of these requests. Amazon appears to be unwilling to fix this issue. This means you cannot support chunked requests from the browser if you target a CF endpoint or make any REST calls that require an Authorization header.
There is also an issue the prevents you from targeting differing CloudFront distribution endpoints (in order to more easily target different S3 from the same CF domain).