How to trigger an AWS Lambda when the user signs up in AWS Cognito

How to trigger an AWS Lambda when the user signs up in AWS Cognito
Trigger AWS Lambda when user signs-up in AWS Co

In this article, we're going to discuss how to trigger an AWS Lambda when a user signs up

Whenever a user signs up, we want cognito to call a lambda function with the user's metadata so that we can save that data in dynamodb or do further processing.

Why you may need to store the user's metadata?

There are some instances where you may need to get the user's metadata information. For example, you may have an admin dashboard in your application - where you have a list of the users sorted by the date they signed up. You may also create a report where you want to know how many users have signed up for your application every month.

Infrastructure

The infrastructure for this setup is pretty straightforward.

  • Cognito user pool & app client for the same
  • AWS Lambda function

Cognito User Pool:

Let's create a simple Cognito pool

const cognitoSamplePool = new cognito.UserPool(this, "cognitoSamplePool", {
      userPoolName: "cognito-sample-pool",
      signInCaseSensitive: false, // case insensitive is preferred in most situations
      selfSignUpEnabled: true,
      accountRecovery: cognito.AccountRecovery.EMAIL_ONLY,
      mfa: cognito.Mfa.OFF,
      userVerification: {
        emailSubject: "Verify your email for Cogntio Sample App",
        emailBody:
          "Hey, Thanks for signing up to Cognito Sample App. Your verification code is {####}",
        emailStyle: cognito.VerificationEmailStyle.CODE,
      },
      signInAliases: {
        email: true,
        username: false,
      },
      standardAttributes: {
        email: {
          required: true,
        },
      },
    });

Let's add an app client for the user pool that we've created

   const appClient = cognitoSamplePool.addClient("cognito-sample-app-client", {
      userPoolClientName: "cognito-sample-app-client",
      generateSecret: true,
      authFlows: {
        userPassword: true,
      },
      oAuth: {
        flows: {
          authorizationCodeGrant: true,
        },
        callbackUrls: ["http://localhost:3000/api/auth/callback/cognito"],
        logoutUrls: ["http://localhost:3000"],
        scopes: [
          cognito.OAuthScope.EMAIL,
          cognito.OAuthScope.OPENID,
          cognito.OAuthScope.PROFILE,
        ],
      },
    });

Let's add a domain prefix to the user pool so that the URL will contain these customized subdomain name

   cognitoSamplePool.addDomain("CognitoDomain", {
      cognitoDomain: {
        domainPrefix: "cts-auth-sample-app-2205",
      },
    });

Lambda function

Below is the lambda function configuration

  const postConfirmationLambda = new NodejsFunction(
      this,
      "PostConfirmationLambda",
      {
        entry: "lambdas/post-confirmation-lambda.ts",
        ...nodeJsFunctionProps,
        functionName: "cognito-sample-app-post-confirmation-lambda",
      }
    );

I'm going to write a simple lambda function. This lambda function resides in lambdas folder.

export async function handler(event: any, context: any) {
  console.log("This lambda is called after a user has been confirmed.");
  // You can use this lambda to store metadata about the user in the database
  console.log("event: ", event);
  return event;
}

Connecting the lambda function to Cognito:

You can use the addTrigger method to configure the trigger for POST_CONFIRMATION. This would call our lambda function when user confirmation completes.

  cognitoSamplePool.addTrigger(
      cognito.UserPoolOperation.POST_CONFIRMATION,
      postConfirmationLambda
    );
  }

Deployment & Testing:

You can use the cdk deploy command to deploy the stack and whenever you create a user and user confirms by clicking the link or entering the confirmation code, the lambda will be called.

Please let me know your thoughts in the comments.