7

I use AWS Lambda + Cognito (User Pool + Federated Identity) + API Gateway. Users authenticate in WEB application with amazon-cognito-identity-js and invokes API with aws-api-gateway-client. API Gateway methods have AWS_IAM authorizer. How to get username (from User Pool) in Lambda function?

Ildar
  • 3,808
  • 7
  • 45
  • 81
  • How is this a different question from your previous post(s)? https://stackoverflow.com/questions/46120881/how-to-get-cognito-user-in-aws-lambda https://stackoverflow.com/questions/46108431/using-aws-lambda-with-cognito-and-api-gateway – Mark B Sep 08 '17 at 23:32
  • Related: https://stackoverflow.com/questions/37963906/how-to-get-user-attributes-username-email-etc-using-cognito-identity-id – jarmod Sep 09 '17 at 00:05
  • @MarkB I've removed that post – Ildar Sep 09 '17 at 06:53

2 Answers2

3

You can use event.identity.username

exports.handler = async (event, _, callback) => {
   try {
        console.log('event', event);
        console.log('event.identity.username', event.identity.username);
        const userId = event.identity.username;
        console.log('userId', userId);

        callback(null, true);
   } catch(e) {
       console.log(e);
       callback(e);
   }
};
аlex
  • 5,426
  • 1
  • 29
  • 38
  • 1
    event.identity dosent have a field named username. Am I missing something? – Vikas Saini May 19 '22 at 12:27
  • @VikasSaini hmm, maybe because of you not use cognito? – аlex May 20 '22 at 13:02
  • Ok let me share more details, apologies for delay in comment response. I use Cognito User Pool + Identity Pool, my lambda is in VPC behind API gateway secured via IAM Authorizer. After passing APIG, my lambda receives the event that contains event.requestContext.identity , now this object dosent have much information, only cognitoIdentityPoolId, cognitoAuthenticationType, cognitoAuthenticationProvider. Ofcourse I can get sub Id from this but I wanted email, name, groups etc. For this I had to do another call to cognito which takes another 500ms – Vikas Saini May 21 '22 at 06:06
  • 1
    @VikasSaini I guess if you use IAM Authorizer it would not work, try to change type – аlex May 23 '22 at 08:47
2

Modify the request sent to your Lambda function using aws-api-gateway-client to pass the JWT ID Token in the request header. You may need to ensure your API gateway is configured to forward headers.

apigClient.invokeApi(
  params,
  pathTemplate, 
  method,
  { { headers: { IDToken } } }, 
  body);

The ID Token should be used here as its payload contains cognito:username field

The ID Token is gotten after authentication using amazon-cognito-identity-js.

You can parse this field from the header of the request in your lambda handler function.

Verify its signature before trusting the contents of its payload.

import { util } from 'aws-sdk/global';

exports.handler = function(event, context) {
  // Parse ID Token from request header
  const headers = event.headers;
  const idToken = headers.IDToken;

  ...
};
Oluwafemi Sule
  • 36,144
  • 1
  • 56
  • 81
  • 1
    You cannot securely encrypt a token on the client side and expect it to be untouched on the server side. Retrieving details from a JWT token without checking the signature is very unsafe. – Bram Jan 26 '19 at 14:34
  • 1
    You make a good point about not trusting the JWT token. My answer can be updated to forward the IDToken since that contains the Cognito username. – Oluwafemi Sule Jan 27 '19 at 14:01