How to pass Cognito User Pool information to Lambda through API Gateway
Question:
I have a REST API on API Gateway that is using a Cognito User Pool authorizer, with the API invoking a Lambda function. In the Lambda function I want to be able to use the Cognito User Pool information (e.g. id token, user id, email), but I can’t seem to get it work.
From googling it seems like the best ways are either to use a body mapping template to reformat the context data:
#set($inputRoot = $input.path('$'))
{
"user_id" : "$context.authorizer.claims.sub"
}
or to set in the Integration settings Use Lambda Proxy Integration = True
and then extract the user data with something along the lines of this:
def lambda_handler(event, context):
user_id = event.requestContext.authorizer.claims.sub
However both methods aren’t working. The first gives the error that there is no user_id
in the context:
def lambda_handler(event, context):
user_id = context["user_id"] # <- fails
The second only returns (what I assume to be) the event body data, with no requestContext
attribute.
My Integration Type is set as Lambda. Is there something I’m missing?
Answers:
So for anyone else in a similar situation, I ended up just deleting the API and remaking it, and then it worked for both scenarios. I’m guessing that like most things with AWS, you’re better off deleting and starting over than trying to change settings after it’s already been made.
You can access the Cognito claims the following way:
claims = event['requestContext']['authorizer']['claims'] # that's a dict
This contains what you are looking for.
As a sidenote, Lambda events are somewhat complicated in their structure sometimes. I’m in the process of developping awsmate
, a Python lib that aims to make them easier to use, among other things: https://awsmate.readthedocs.io/
In your case, the code would look like:
from awsmate.apigateway import LambdaProxyEvent
def lambda_handler(event, context):
apigateway_event = LambdaProxyEvent(event)
claims = apigateway_event.authorizer_claims() # No need to look for where it is in the raw event
I have a REST API on API Gateway that is using a Cognito User Pool authorizer, with the API invoking a Lambda function. In the Lambda function I want to be able to use the Cognito User Pool information (e.g. id token, user id, email), but I can’t seem to get it work.
From googling it seems like the best ways are either to use a body mapping template to reformat the context data:
#set($inputRoot = $input.path('$'))
{
"user_id" : "$context.authorizer.claims.sub"
}
or to set in the Integration settings Use Lambda Proxy Integration = True
and then extract the user data with something along the lines of this:
def lambda_handler(event, context):
user_id = event.requestContext.authorizer.claims.sub
However both methods aren’t working. The first gives the error that there is no user_id
in the context:
def lambda_handler(event, context):
user_id = context["user_id"] # <- fails
The second only returns (what I assume to be) the event body data, with no requestContext
attribute.
My Integration Type is set as Lambda. Is there something I’m missing?
So for anyone else in a similar situation, I ended up just deleting the API and remaking it, and then it worked for both scenarios. I’m guessing that like most things with AWS, you’re better off deleting and starting over than trying to change settings after it’s already been made.
You can access the Cognito claims the following way:
claims = event['requestContext']['authorizer']['claims'] # that's a dict
This contains what you are looking for.
As a sidenote, Lambda events are somewhat complicated in their structure sometimes. I’m in the process of developping awsmate
, a Python lib that aims to make them easier to use, among other things: https://awsmate.readthedocs.io/
In your case, the code would look like:
from awsmate.apigateway import LambdaProxyEvent
def lambda_handler(event, context):
apigateway_event = LambdaProxyEvent(event)
claims = apigateway_event.authorizer_claims() # No need to look for where it is in the raw event