Separate CloudFront cache behaviors per request method? - amazon-cloudfront

Can I have separate cache behaviors per path + request method? Ex: get /users, post /users?
I want to include a LambdaEdge in the 'post /users" behavior, which will add headers for the Cognito user pool authorizer in Api Gateway. For the 'get /user' I don't need the Lambda Edge.
I guess it's not possible, so I will have to add the EdgeLambda to the whole '/users' pattern.

Related

Is it the correct place to store a header parameter in process.env for having different behaviour into my API application?

This is my context:
A NodeJs application deployed as lambda function offering an API.
I'd like to reuse the same application to offer different content depending on a request header.
So having this header "x-custom-header" sent through with the request I'd like to load a different configuration
and to provide a specific outcome payload.
When I get the request I'd like to store this header value into object
process.env.mycustomHeader = requestHeader["x-custom-header"];
so I can possibly load on any file of the app the right configuration object like:
const config = getConfig(process.env.mycustomHeader);
Now : this is working fine on a single request test
But I'm worried and investigating about the behaviour of this process object in NodeJs w/ Lambda.
Can I be sure that this object life and scope is limited to a single request?
And there's no way that multiple different request might conflict accessing this process?
And lambda does not possible share reuse same NodeJs process, messing up with my idea/setup?
Any other better proposal to solve this use-case is welcome.
If you construct the object inside the lambda handler method, it will execute with each function call.

can i use one backend request for couple endpoints?

http://localhost:4200/product-list?gender=2&category=4
http://localhost:4200/product-list?gender=2
http://localhost:4200/product-list?category=4
i want to use one backend controller for the endpoints.
can i do that? i tried but with no success. (using angular)
What exactly did you try with angular? The backend controller? Angular is a frontend framework.
However, you could indeed have one single controller (e.g. ProductController) for your endpoints. I would suggest implementing a "getProducts" method that can be filterable. That way you can use single endpoint and provide optional filter options as needed.
I may not understand your question entirely, so please stat otherwise. But, Yes. You have one endpoint stated above, with different query params. Depending on the different query params (their value or even if they are present), your singular endpoint can do something different.
So your endpoint is
http://localhost:4200/product-list
This endpoint (which there is only one), can have as many query params as you like. As per the response above, Angular does not handle this, this would be some backend functionality for your end point, to read the request, and based on what query params are 'found' then trigger a different response.

QR code best approach for POST request from REST API

I'm setting up a website that will be mobile focused and one of the features I wan't to implement is users to be able to log an entry by just scanning a QR code.
For what I read is not really possible to make a POST request directly from a QR code, so I was thinking in two different options:
1. Make a GET request and then redirect that inside my server to a POST route in my routes.
So the URL would be something like https://example.com/user/resources/someresourceid123/logs/new and then this would create a POST request to https://example.com/user/resources/someresourceid123/logs/ and create the new entry to then send a response to the user but I'm not really sure this is the best approach or if it's possible at all.
My POST request only requires the resourceid which I should be able to get from req.params and the userid which I get from my req.user.
2. Do my logic and log the entry to my DB using the GET request to https://example.com/user/resources/someresourceid123/logs/new.
This would mean that my controller for that request will do everything needed from the GET request without having to make an additional POST request afterwards. I should be able to get both the resourceid and userid from the req object but not sure if being a GET request limits what I can do with it.
If any of those are possible, which would be the best approach?
I'd propose to go with a second option simply for the sake of performance. But you need to make sure your requests are not cached by any proxy, which is usually the case with GET requests.

Can a REST API works as a PROXY for CORS issues?

My problem is as follows :
I'm developping a web application with Angular. Angular application runs on the client's browser. In its logic, my application needs data from other-domain.com.
I can't use directly XMLHttpRequest() because of CORS policy problems. (The web server other-domain.com producing data is not my domain and cannot add 'Control-Access-Allow-Origins')
So instead of having :
Angular ===>> other-domain.com (forbidden because of CORS)
I'm creating a REST API that will get data from other-domain.com and wraps this data with header 'Access-Control-Allow-Origin' : '*' before sending to client's Angular.
So my workflow becomes :
Angular ==>> my API server ==>> other-domain.com (allowed because request for other-domain does not execute on the browser)
Do you think my idea works well forevery request (GET, POST, adding cookies header) ? In that case the API I'm developping acts as a proxy, right ?
Thank you
Short answer: yes. In fact, there's packages and sites out there that will do this for you.
But I think another question is why you have the need to circumvent CORS restrictions. After all, it is working as intended and there's a reason for its existence in the first place.
If you have a backend already, can you add an endpoint where your backend will make the call to the other domain, and leave the browser to communicate only within your domain?
If you're only doing RESTful GETs and an opaque request (no credentials, no cookies, etc.) will suit your needs, you could also just use the fetch api with {mode: 'no-cors'}; however, you'd need to 'circumvent' the HttpClient to do so and you'd need a polyfill if you need to support IE.

Modify a CloudFront request before logging?

I'm building an ELK stack (for the first time) to track end-user REST API usage for a CloudFront distribution (in front of an S3 origin). Users pass a refresh token as part of their request and I was hoping to use this token to identify which users were making which request. Unfortunately, it looks like CloudFront access logs are missing some header information (particularly Authorization/Accept in my use case). This leaves me with three questions:
Is there a way to tell CloudFront to log additional items? It appears the answer is no.
As an alternative strategy, I tried modifying the request object with lambda#edge (in Viewer Request) to move the header information into the query string (so that it would get logged) but any manipulation in lambda#edge does not seem to be reflected in the log. (though it is reflected in the Origin Request function). Should this be possible?
If doing what I want is impossible, I think the alternative approach is forgo CloudFront logs completely and just fire an http request to logstash with every user request, but I feel like this could be easy to overload.
Thanks
After a few days of research and reaching out to Amazon, I was finally able to answer my own questions:
CloudFront logs can't be customized, they are what they are.
See 1.
It turns out that customization is the wrong approach. What I really need to do is aggregate two separate logs that have the information I need into a single logstash entry. It turns out that the Viewer Response lambda#edge function contains a requestId property (actually event.Records[0].cf.config.requestId) which matches the CloudFront log x-edge-request-id column. So while I haven't finished implementing it yet, these two columns can be used in the logstash config for aggregation. I just need to make sure I set up a Viewer Response event that logs out a consistent format that I can then part with logstash. I'm using the logstash-input-cloudwatch_logs to retrieve teh cloudwatch logs.

Resources