AWS Cloudfront Error "IncompleteSignatureException" when accessing API Gateway Origin/Behavior - amazon-web-services

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.

Related

AWS S3 is not connecting with API Gateway due to CORS errors

I'm hosting my react application's build on S3 bucket, and I also have a lambda function running for my API using AWS's API-Gateway.
I'm trying to send a post/get requests from my static website to this API gateway (which is also using API KEY to authorize) and I'm getting CORS error for no reason.
I've tried to debug it using postman and everything works great.
I've added x-api-key to the default headers of axios in my application and inserted the key as requested.
Is there a problem using S3 for hosting a static website that uses POST/GET requests?
btw: I've allowed CORS in my API-gateway (as I said, it works on Postman)
Thanks!

API Gateway Invoke Endpoint works fine; Cloudfront returns 403

I've set up an AWS API Gateway proxy endpoint to a lambda function and deployed it to a stage called auth. The Invoke URL found on the API Gateway dashboard works just fine and executes my lambda.
However, I've created a Cloudfront distribution that I want to map to API Gateway. I set the Origin to the API Gateway URL and configured a behavior to forward /auth/* to the API Gateway origin:
Origin Settings:
Behavior Settings:
However, this doesn't work. I get a 403 Forbidden message from Cloudfront:
This is extremely confusing for me because I have an almost identical set up on another AWS account that works just fine. Does anyone know what the problem might be?

AWS API Gateway with custom domain and CORS

I have an AWS API Gateway API with CORS enabled and a custom domain set-up. Direct API access via the execute-api endpoints is working and I get no CORS issues in the browser. Access via the custom domain api.example.com which I also configured, is working in principle, but not in the browser, where I get CORS:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
When setting up the custom domain, API Gateway configures its own CloudFront distribution which is somewhat internal and I do not see how to configure it or if this is even possible, it does not show up in my list of CloudFront distributions, which is expected. From the AWS docs:
The CloudFront distribution created by API Gateway is owned by a
region-specific account affiliated with API Gateway
I found these answers https://stackoverflow.com/a/52435619/4556546 and https://stackoverflow.com/a/51463965/4556546 that describe how to solve the problem with a normal CloudFront distribution. I am, however wondering:
Have I missed something in configuring the custom domain and its
associated CloudFront distribution?
In what circumstances would I choose the custom domain with its internal CloudFront distribution over running my own CloudFront distribution
that I can configure? (I already have a CloudFront distribution that I use for other parts of my app.) Are there pricing implications?
Your suggestion to remove the stage or "/dev" from my new custom domain worked like a charm.
api.example.com/dev/some_endpoint Incorrect
api.example.com/some_endpoint Correct
Hopefully this answer can help anyone else trying to add a custom domaim to AWS API Gateway.
simply removing /dev from the end of my custom domain in my amplify config nailed it! I want to hide under the sheets everytime I see that cors error, in this case I came out on top, thanks!

Routing POST requests from CloudFront to Lambda

I have a website distributed with CloudFront, with S3 as an origin. I've written a Lambda function that takes a contact form submission and sends the email along with SES. The Lambda test out just fine : )
But, I'm clueless when it comes to routing POST requests from CloudFront to that backend Lambda function. How do I do this?
Update: Okay, I've got the API Gateway test triggering the Lambda function just fine, but I can't seem to call it from CloudFront (or rather using a curl command to my domain set up with CloudFront).
Do I need to list my domain as a custom domain in API Gateway?
If I list the path /api/* in my CloudFront Behaviors, do I have to mirror that in my API Gateway set up? So, does my API Gateway need to start with /api before I add specific resources?
Update 2 I think I needed to leave or remove the /dev off the end of the API Gateway URL. dev being my stage.
Update 3 Okay, it feels one step away now. I've got everything hooked up. The test request hits cloudfront, it forwards to api gateway, gateway calls lambda (at this point I'm shaking my head at how complicated we've made all this), and lambda sends back success or failure to api gateway, and we're peachy. Except, I get MethodNotAllowed when I do it from curl or the browser. Do I need to add an IAM role to CloudFront to access API Gateway?
Update 4 Still not working. And now, I'm back to getting my usual 404 error page that my Default Origin (S3). Seems like serverless is a fading dream.
Update 5 Trying a different approach, recommended here: https://serverfault.com/a/839368 The idea is to use API Gateway's Custom Domain name features with a subdomain like api.example.com and then use a Route53 Alias record to direct subdomain traffic to API Gateway. This could work. Then CloudFront would handle traffic to example.com and www.example.com, and API Gateway would get requests to api.example.com. Now the challenging bit is that in HTML forms the action attribute will have to go to a different subdomain. Let's see what kinds of errors and crazy behavior we get : (
First you would setup API Gateway in front of your Lambda function so it can be called via a POST request. It sounds like you may already have that part done?
Then if you want the POST to go through CloudFront you would add a second origin in CloudFront that points to your API Gateway.
This is all possible, but its tricky to configure. To help I created an open-source boilerplate app that correctly sets up:
A static site with CloudFront and S3
An API with API Gateway and Lambda
CORS between the static site and API
Optional OAuth 2.0 and JWT cookie for the static site
See this static JavaScript app for an example of a static site POSTing to an API backed by Lambda.
Depends on what you're using as your backend (which language, framework, etc.), there are different ways, but 'em all about one thing: Invoke
Kind-of the most generic call - HTTP is right there, the API call examples by language are referenced at the end of the doc.

AWS API Gateway Custom Domain + AWS CloudFront

I have an AWS API Gateway endpoint(Invoke URL),
I created a Custom Domain, to map the Domain with my API Gateway as the Invoke URL is made of non user friendly characters,
I mapped the Custom Domain with the API Gateway,
I followed these steps -
http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html
Both the Default Invoke URL and Custom Domain endpoint are responding correct data,
So far so good.
On further testing I found out that as my default Invoke URL had Caching enabled on it,
I enabled API Gateway cache by following this -
http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-caching.html
The response was in miliseconds,
Weirdly the Custom Domian mapped endpoint is responding slower and looks like it is not Caching the previous responses, even though Caching is properly enabled on the API Gateway,
I need to Enable Caching on the Custom Domian as well,
Do I need to add CloudFront in front of the API Gateway or something?
How do I achieve this?
I am not able to find my Invoke URL in CloudFront origin,
I couldn't understand these solutions either -
1. http://www.davekonopka.com/2016/api-gateway-domain.html
2. How do you add CloudFront in front of API Gateway