I have a react application uploaded on S3 and node application on Lambda which has endpoints available for only authenticated users. Authentication on React app is done by Cognito, I have hardcoded Google Sign in button. After authentication, user is redirected to S3 endpoint(/Code) which gets the code=... from URL, sends it using Axios to specific Lambda endpoint. From Lambda side when it receives code it gets token from /oauth2/token and sends it back to S3, which sets it as a cookie using universal-cookie package. After this S3 sends every request to Lambda using {credentials: true}
For Cognito authentication to work properly, it needs login Callback url to be HTTPS. I created a Cloudfront distribution to forward requests to S3. So I setup my callback url to be Cloudfront URL. The authentication is done correctly and I can see that cookie is set and is sent in every request:
But it's not forwarded to S3, I see a request that is sent to Lambda:
Which doesn't contain the cookie. I changed Cloudfront behaviour:
But it didn't help. I'm missing some knowledge in Cloudfront. Should I set some other option to forward Cookies to S3?
Related
Reading this page https://docs.aws.amazon.com/AmazonS3/latest/userguide/cors.html it states that :
Your users load the website endpoint: http://website.s3-website.us-east-1.amazonaws.com
Now you want to use JavaScript on the webpages that are stored in this bucket to be able to make authenticated GET and PUT requests against the same bucket by using the Amazon S3 API endpoint for the bucket, website.s3.us-east-1.amazonaws.com. A browser would normally block JavaScript from allowing those requests
Why would a browser require CORS to be enabled for requests back to the same server that hosts the static content ? i.e. website.s3.us-east-1.amazonaws.com.
I can understand confusion, it could be rewritten better.
S3 REST API endpoints are of the format s3.us-east-1.amazonaws.com and website endpoints are website.s3.us-east-1.amazonaws.com
When we host website and do GET/PUT requests, they call s3 api with param as bucket name (website) and path. Hence, CORS is needed.
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.
Let's say I have a service to allow people to upload photos. I store these photos in S3, and to make it efficient, I use Cloudfront. In order to upload these photos to S3, I was recommended to use Lambdas with API Gateway. However, I'd also like to send this request to a custom HTTP endpoint as well, and return that in the response from the Gateway. So my ideal process is:
User submits upload photo
Photo gets sent to API Gateway
API Gateway calls Lambda to store photo in S3 and also forwards the request to custom backend API
Backend sends back some info
API Gateway sends back this info to client
Is this possible? From the integrations doc, it seems like I can only do Lambdas or HTTP custom endpoint. Not sure how to do both.
Your flow should be like this
Create a lambda endpoint to create signedUrl and return to frontend for s3 upload
Once you have the signed URL upload the pic to the signed URL from the frontend
Once the operation is successful either you can send a request to the lambda from the frontend or a event on the s3 bucket to do further processing
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!
I have a CloudFront distribution where the origin is set to an s3 website endpoint (serving static web app on s3)
Now my webapp on s3 needs some user information that is only provided via a POST request from an iframe.
I thought it would be possible to use Lambda#edge function on ViewerRequest stage, to capture the user info, and then modify the request to GET and append a token to the origin, before it requests the origin, thus allowing s3 to serve.
However i can't seem to get it to work. is this even possible?
You can't change the HTTP method in a Lambda#Edge trigger function, because it is read-only.
method (read-only)
The HTTP method of the viewer request.
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html#lambda-event-structure-request
What you can do is use the AWS SDK to send a request to S3 from within the trigger function, and use the object content retrieved, to generate a response directly from the trigger function.
Note that there are limits to the response size you can generate -- for Viewer Request, it's 40KB. For Origin Request, it's 1MB.
Of course, you don't need to fetch the content from S3, necessarily. You can fetch it from anywhere, or you can embed it in the function itself.
With this setup, since the function is generating a response, CloudFront never forwards the actual POST request to S3.