How to custom client request in AWS API Gateway + Lambda(JWT Auth) - node.js

aws structure picture
JWT authorization (verify) is in progress in AWS Lambda.
I want to put the decoded data into the client request headers.
Becuase, I don't want to decode the token again at the 'service' and use it.
How to custom the client request?
AWS lambda 'event.headers' is undefined. so, 'event.headers.user' is not possible.
Is there any other good way?

You don't adjust the request you need to adjust the event that is being send to the lambda from the authoriz.
You can use the context of the authorizer.
The context can be accessed in the lambda that is handling the request.
context.authorizer.property
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-lambda-authorizer.html

Related

CORS: PreflightMissionAllowOriginHeader aws API gateway lambda

I have node/express APIs running in Lambda function.
The API endpoint is {domain}/api/user/{username} where I pass username in URL itself.
example: to get userA detail, endpoint will be xxx.com/api/user/userA
also sending user_id:xxx in header.
Hitting above endpoint using API gateway/Lambda returns the data without any error.
Problem occurs when I use % in username.
Assume I have username as userA% .
Endpoint would become: xxx.com/api/user/userA%
Now, the problem is when I run this in my local machine with node/express/mysql api with endpoint localhost:2000/api/user/userA%, it returns the data.
But the same API using API gateway/Lambda : xxx.com/api/user/userA% throws
CORS: PreflightMissionAllowOriginHeader.
I have configured some CORS policies as shown in below image but can't seem to figure out what should I configure more to allow this type of requests.

Reading Custom Headers on Lambda Edge request

I am using a Lambda Edge triggered by viewer-request to control access to a Cloudfront Distribution Origin (S3 Bucket). I want to allow/deny access to the distribution by sending an IdToken and a UID (user ID) string.
My code basically decodes the IdToken and reads a decodedUID inside it, then compares it to the UID passed as a header and if they match or not it allows/deny access to the Origin
I am using SAM to deploy all of this, when I test this code locally it works as it should but when I deploy the changes to AWS one of the two headers is not being received by the lambda
I am sending two headers with each request to the Cloudfront Distribution
Authorization
UID
But the UID Header is never reaching the lambda edge in the event
I am using Nodejs14.x as runtime, when I run console.log(request.headers) I see the Authorization header with the token but not the UID
Does someone know why is this happening and how can I fix it?
I managed to send the UID value as a query parameter but that solution is not fitting to what I need

Google API Gateway + Firebase: X-Apigateway-Api-Userinfo vs X-Forwarded-Authorization headers

I'm using Google API Gateway to in my Firebase app to verify if a user is signed-in. In API Gateway's documentation here, it recommends to use the forwarded X-Apigateway-Api-Userinfo header to retrieve user info:
API Gateway will send the authentication result in the X-Apigateway-Api-Userinfo to the backend API. It is recommended to use this header instead of the original Authorization header. This header is base64url encoded and contains the JWT payload.
Because it is base64url-encoded, I need extra server-side logic to decode this, just to get the logged-in user's info (I assume the decoded object corresponds to Firebase Auth Admin SDK's DecodedIdToken)).
On the other hand, I found that although API Gateway modifies the original Authorization header, it first copies it to another header named X-Forwarded-Authorization. This means I could do something like:
// authHeaders = 'Bearer ...'
const authHeaders = headers['X-Forwarded-Authorization'];
const token = authHeaders.split(' ')[1]
const decodedToken = await admin.auth().verifyIdToken(token)
which I find is an easier (and better-documented) way to get the same information. Is this a bad idea? I'm not sure if there are other reasons that the X-Apigateway-Api-Userinfo headers are recommended instead.
The API gateway header X-Apigateway-Api-Userinfo works the same as Cloud Endpoints X-Endpoint-API-UserInfo, which verified the JWT signature for you and store only JWT payload you can trust.
If you want to do authentication again or by yourself, you can read the X-Forwaded-Authorization and finally decode into a JWT payload. This only makes sense if you want to double check requests to your HTTP headler functions with fake X-Apigateway-Api-Userinfo that bypassing these API gateway services. You can use IAM to protect your functions.
To conclude,
you do not need to verified firebase JWT token because API gateway does that for you.
the verified JWT payload is saved as X-Apigateway-Api-Userinfo
you need to decode the base64 encoded payload string.
Reference:
ESPv2 not forwarding original Authorization header when an x-google-backend is specified

How can I restrict specific parameters in payload from API Gateway to AWS Lambda?

I have to send a request body (payload) from API Gateway to AWS Lambda. In that payload, I only need to send:
{
"path":"aaa"
"action":"xyz"
}
If someone passes any other parameter in the payload, it should not accept the payload and show an error message. Could somebody please help me with the logic?
For AWS API Gateway you can implement request validation using an OpenAPI template. The extension should work for both Rest and Http APIs.
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-method-request-validation.html
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions-request-validator.html
For even more flexibility you could implement a Lambda authorizer which evaluates the body, but of course this leads to more costs as well:
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-lambda-authorizer.html

Unable to get response from aws api gateway?

I have deployed my api on aws amazon api gateway and If I go through resource and make a request to an endpoint, I am able to get the response however when I go to stages and invoke url with params and x-api-key then I don't get any response with warning 'Unexpected 'N'' and 'Not Acceptable'. How is it possible that output is changed after deploying?
I found out what I was doing wrong, for all the post request body needs to be sent as form-data, when I changed body from form-urlencoded to form-data, I got the response...Thats very naive of me.

Resources