Cloudfront removes Set-Cookie header from response to viewer - cookies

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.

Related

set-cookie header Is removed by AWS HTTP API Gateway

I writing a serverless website using Amazon Web Services S3, Lambda, and the HTTP API Gateway, not the REST API Gateway. I am trying to set a cookie with one of my lambda functions and it works when I hit the lambda function directly using the lambda function url, but when I hit the url using the HTTP API Gateway, the Set-Cookie header is stripped off. The body, and all other custom headers are present, but the set-cookie header is just gone.
I've tried with and without the domain=***.com in the header and that doesn't make a difference.
I've tried messing with CORS and enabling Access-Control-Allow-Credentials. I've set Access-Control-Allow-Origin to the correct domain name. I've tried both set-cookie and * for Access-Control-Allow-Headers and Access-Control-Expose-Headers. Although I don't think CORS really matters because I'm using Postman and my understanding is it doesn't require CORS.
Does the HTTP API Gateway just not support setting cookies? It would be great if that was documented somewhere.
I forgot that I was using CloudFront. By default CloudFront does not forward cookies to or from the origin, so I had to set the CloudFront caching policy to allow that. More information here: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Cookies.html

AWS Cloudfront Error "IncompleteSignatureException" when accessing API Gateway Origin/Behavior

I am struggeling to get my AWS cloudfront/apigateway setup right. I have a cloudfront with two origins pointing to the same ApiGateway but of different routes. /* as default should be routed to /dev/react and /api/* should be routed to /dev/api/ on the Apigateway. /dev/react is a SSR Lambda rendering a react web page and /dev/api are my API Lambdas. The API Lambdas are protected by the Cognito Authorizer for which I am sending the Authorization header on every request.
This works very well when I serve everything on the ApiGateway domain, no Auth errors or such, but when I try to serve/access it via the cloudfront I can load the react app, via the default behaviour, but when the react app calls the API endpoints I get a IncompleteSignatureException.
I tried forwarding the Host header and other things, but cannot get it to work.
I found this ApiGateway403Erros page where the expl. is A request with an "Authorization" header is sent to an API resource path that doesn't exist., but I can pin point what that means for my scenario?
Is my routing bad? Am i missing an alias domain on the ApiGateway? What makes cloudfront not "finding" the resources on this path?
Any hints would be very much appreciated.

AWS Cloudfront CORS headers without S3 bucket

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.

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.

whitelist Authorization header in Cloudfront

I'm using OAuth2 with my PHP EC2 server.
From my frontend client hosted in S3, I'm making requests to my ElasticBeanstalk EC2 server (both frontend and backend are served through Cloudfront with SSL cert).
These requests are sent with required access token header as Authorization: header ...
It seems Cloudfront strips these headers as I'm getting error:
error_description: "The request is missing a required parameter,
includes an invalid parameter value, includes a parameter more than
once, or is otherwise malformed. Check the "access token" parameter."
I'm trying to "whitelist" this header through Cloudfront as instructed by this documentation but find it very confusing. Where in Cloudfront can I actually add the Authorization header to accept?
Part of the docs say:
You can configure each cache behavior in a web distribution to do one
of the following:
Forward all headers to your origin
But I've already done this when I set it up:
You need to specifically whitelist headers you want, otherwise choosing None (Improves Caching) strips headers needed: