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
Answered By: Shlublu