Menu
Amazon Cognito
Developer Guide

AWS Lambda Trigger Examples

This section gives code examples for each type of AWS Lambda trigger.

Pre Sign-up Example: Auto-Confirm the User

The following example initializes just before the service starts the new user registration process. With this Lambda function, you can add custom logic to validate, filter, or restrict the types of user accounts that can be registered. For example, you may only want to allow users to register if they have been invited to join the service. This example uses the autoConfirmUser flag to indicate whether to auto-confirm a user to the user pool.

exports.handler = function(event, context) { // This Lambda function returns a flag to indicate if a user should be auto-confirmed. // Perform any necessary validations. // Impose a condition that the minimum length of the username of 5 is imposed on all user pools. if (event.userName.length < 5) { var error = new Error('failed!'); context.done(error, event); } // Access your resource which contains the list of emails of users who were invited to sign up // Compare the list of email IDs from the request to the approved list if(event.userPoolId === "yourSpecialUserPool") { if (event.request.userAttributes.email in listOfEmailsInvited) { event.response.autoConfirmUser = true; } } // Return result to Cognito context.done(null, event); }; { "version": 1, "triggerSource": "PreSignUp_SignUp", "region": "<region>", "userPoolId": "<userPoolId>", "userName": "<userName>", "callerContext": { "awsSdk": "<calling aws sdk with version>", "clientId": "<apps client id>", ... }, "request": { "userAttributes": { "email": "<email>", "phone_number": "<phone_number>", ... }, "validationData": { "k1": "v1", "k2": "v2", ... } }, "response": { "autoConfirmUser": false } }

Pre Sign-up Example: Auto-Confirm and Auto-Verify the User

The following example is similar to Example #1, except that it automatically confirms the user and automatically sets the user's email and phone_number attributes to verified if the attribute is present.

If aliasing is enabled, aliases will be created for phone_number and email when auto-verify is set. If an alias with the same phone number already exists, the alias will be moved to the new user, and the previous user's phone_number will be marked as unverified. The same is true for email addresses. If this is not the desired behavior, you can use the ListUsers API to see if there is an existing user who is already using the new user's phone number or email address as an alias.

exports.handler = function(event, context, callback) => { //console.log('Received event:', JSON.stringify(event, null, 2)); // TODO Confirm this is a user that should be auto-confirmed, e.g., has a valid token in event.request.validationData var autoConfirm = true; if (autoConfirm) { event.response.autoConfirmUser = true; console.log('Auto confirmed user'); if (event.request.userAttributes.hasOwnProperty("email")) { event.response.autoVerifyEmail = true; console.log('Set email verified'); } if (event.request.userAttributes.hasOwnProperty("phone_number")) { event.response.autoVerifyPhone = true; console.log('Set phone_number verified'); } } callback(null, event); };

Pre Authentication Example

This sample function restricts users from a specific app client ID from authenticating.

exports.handler = function(event, context) { if (event.callerContext.clientId === "<client id to be blocked>") { var error = new Error('Cannot authenticate users from this client'); context.done(error, event); } context.done(null, event); };

Sample event parameter:

{ "version": 1, "triggerSource": "PreAuthentication_Authentication", "region": "<region>", "userPoolId": "<userPoolId>", "userName": "<userName>", "callerContext": { "awsSdkVersion": "<calling AWS sdk with version>", "clientId": "<apps client id>", ... }, "request": { "userAttributes": { "phone_number_verified": false, "email_verified": false, ... // All custom attributes }, "validationData": { "k1": "v1", "k2": "v2", ... } }, "response": {} }

Custom Message for Sign Up Example

This Lambda function is invoked to customize an email or sms message when the service requires an app to send a verification code to the user.

A Lambda trigger can be invoked at multiple points: post-registration; resending a verification code; forgotten password; or verifying a user attribute. The response includes messages for both SMS and email. The message must include the code parameter, "####", which is the placeholder for the verification code that is delivered to the user.

For email, the maximum length for the message is 20,000 UTF-8 characters, including the verification code. HTML tags can be used in these emails. For SMS, the maximum length is 140 UTF-8 characters, including the verification code.

exports.handler = function(event, context) { // if(event.userPoolId === "theSpecialUserPool") { // Identify why was this function invoked if(event.triggerSource === "CustomMessage_SignUp") { // Ensure that your message contains event.request.codeParameter. This is the placeholder for code that will be sent event.response.smsMessage = "Welcome to the service. Your confirmation code is " + event.request.codeParameter; event.response.emailSubject = "Welcome to the service"; event.response.emailMessage = "Thank you for signing up. " + event.request.codeParameter + " is your verification code"; } // Create custom message for other events } // Customize messages for other user pools // // Return result to Cognito context.done(null, event); };

Sample event parameter:

{ "version": 1, "triggerSource": "CustomMessage_SignUp/CustomMessage_ResendCode/CustomMessage_ForgotPassword/CustomMessage_VerifyUserAttribute", "region": "<region>", "userPoolId": "<userPoolId>", "userName": "<userName>", "callerContext": { "awsSdk": "<calling aws sdk with version>", "clientId": "<apps client id>", ... }, "request": { "userAttributes": { "phone_number_verified": false, "email_verified": true, ... }, "codeParameter": "####" }, "response": { "smsMessage": "<custom message to be sent in the message with code parameter>" "emailMessage": "<custom message to be sent in the message with code parameter>" "emailSubject": "<custom email subject>" } }

Custom Message for Admin Create User Example

A custom message Lambda function with the CustomMessage_AdminCreateUser trigger returns a user name and verification code and so include both request.usernameParameter and request.codeParameter in the message body.

The code parameter value "####" is a placeholder for the temporary password and "username" is a placeholder for the username delivered to your user.

For email, the maximum length for the message is 20,000 UTF-8 characters, including the verification code. HTML tags can be used in these emails. For SMS, the maximum length is 140 UTF-8 characters, including the verification code.

The response includes messages for both SMS and email.

exports.handler = function(event, context) { // if(event.userPoolId === "theSpecialUserPool") { // Identify why was this function invoked if(event.triggerSource === "CustomMessage_AdminCreateUser") { // Ensure that your message contains event.request.codeParameter event.request.usernameParameter. This is the placeholder for the code and username that will be sent to your user. event.response.smsMessage = "Welcome to the service. Your user name is " + event.request.usernameParameter + " Your temporary password is " + event.request.codeParameter; event.response.emailSubject = "Welcome to the service"; event.response.emailMessage = "Welcome to the service. Your user name is " + event.request.usernameParameter + " Your temporary password is " + event.request.codeParameter; } // Create custom message for other events } // Customize messages for other user pools // // Return result to Cognito context.done(null, event); };

Sample event parameter:

{ "version": 1, "triggerSource": "CustomMessage_AdminCreateUser", "region": "<region>", "userPoolId": "<userPoolId>", "userName": "<userName>", "callerContext": { "awsSdk": "<calling aws sdk with version>", "clientId": "<apps client id>", ... }, "request": { "userAttributes": { "phone_number_verified": false, "email_verified": true, ... }, "codeParameter": "####", "usernameParameter": "username" }, "response": { "smsMessage": "<custom message to be sent in the message with code parameter and username parameter>" "emailMessage": "<custom message to be sent in the message with code parameter and username parameter>" "emailSubject": "<custom email subject>" } }

Post Authentication Example

This function is invoked after a user is successfully authenticated. This sample function logs in to the console after a user is authenticated.

exports.handler = function(event, context, callback) => { console.log('User authenticated: User-Pool', event.userPoolId+", UserId:" + event.userName); // Return result to Amazon Cognito context.done(null, event); };

Sample event parameter:

{ "version": 1, "triggerSource": "PostAuthentication_Authentication", "region": "<region>", "userPoolId": "<userPoolId>", "userName": "<userName>", "callerContext": { "awsSdk": "<calling aws sdk with version>", "clientId": "<apps client id>", ... }, "request": { "userAttributes": { "phone_number_verified": true, "email_verified": true, ... //all custom attributes } }, "response": {} };

Post Confirmation Example

The example sends an email message to inform the user that he or she has been confirmed.

var aws = require('aws-sdk'); var ses = new aws.SES(); exports.handler = function(event, context) { console.log(event); if (event.request.userAttributes.email) { sendEmail(event.request.userAttributes.email, "Congratulations "+event.userName+", you have been confirmed: ", function(status) { context.done(null, event); }); } else { // Nothing to do, the user's email ID is unknown context.done(null, event); } }; function sendEmail(to, body, completedCallback) { var eParams = { Destination: { ToAddresses: [to] }, Message: { Body: { Text: { Data: body } }, Subject: { Data: "Cognito Identity Provider registration completed" } }, Source: "<source_email>" }; var email = ses.sendEmail(eParams, function(err, data){ if (err) { console.log(err); } else { console.log("===EMAIL SENT==="); } completedCallback('Email sent'); }); console.log("EMAIL CODE END"); };

Sample event parameter:

{ "version": 1, "triggerSource": "PostConfirmation_ConfirmSignUp", "region": "<region>", "userPoolId": "<userPoolId>", "userName": "<userName>", "callerContext": { "awsSdk": "<calling aws sdk with version>", "clientId": "<apps client id>", ... }, "request": { "userAttributes" : { "email": "<email>", "phone_number": "<phone_number>", ... } }, "response": {} }

Define Auth Challenge Example

This example defines a series of challenges for authentication and issues tokens only if all of the challenges are successfully completed.

exports.handler = function(event, context) { if (event.request.session.length == 1 && event.request.session[0].challengeName == 'SRP_A') { event.response.issueTokens = false; event.response.failAuthentication = false; event.response.challengeName = 'PASSWORD_VERIFIER'; } else if (event.request.session.length == 2 && event.request.session[1].challengeName == 'PASSWORD_VERIFIER' && event.request.session[1].challengeResult == true) { event.response.issueTokens = false; event.response.failAuthentication = false; event.response.challengeName = 'CUSTOM_CHALLENGE'; } else if (event.request.session.length == 3 && event.request.session[2].challengeName == 'CUSTOM_CHALLENGE' && event.request.session[2].challengeResult == true) { event.response.issueTokens = true; event.response.failAuthentication = false; } else { event.response.issueTokens = false; event.response.failAuthentication = true; } context.done(null, event); }

Create Auth Challenge Example

A CAPTCHA is created as a challenge to the user. The URL for the CAPTCHA image is added to the public challenge parameters as "captchaUrl", and the expected answer is added to the private challenge parameters.

exports.handler = function(event, context) { if (event.request.challengeName == 'CUSTOM_CHALLENGE') { event.response.publicChallengeParameters = {}; event.response.publicChallengeParameters.captchaUrl = 'url/123.jpg' event.response.privateChallengeParameters = {}; event.response.privateChallengeParameters.answer = '5'; event.response.challengeMetadata = 'CAPTCHA_CHALLENGE'; } context.done(null, event); }

Verify Auth Challenge Response Example

In this example, the Lambda function checks whether the user's response to a challenge matches the expected response. The answerCorrect parameter is set to true if the user's response matches the expected response.

exports.handler = function(event, context) { if (event.request.privateChallengeParameters.answer == event.request.challengeAnswer) { event.response.answerCorrect = true; } else { event.response.answerCorrect = false; } context.done(null, event); }

Pre Token Generation Example: Add a New Claim and Suppress an Existing Claim

This example uses the Pre Token Generation Lambda to add a new claim and suppresses an existing one.

exports.handler = function(event, context) { event.response = {"claimsOverrideDetails":{"claimsToAddOrOverride":{"attribute_key2":"attribute_value2","attribute_key":"attribute_value"},"claimsToSuppress":["email"]}} console.log(event); context.done(null, event); }

Pre Token Generation Example: Modify the User's Group Membership

This example uses the Pre Token Generation Lambda to modify the user's group membership.

exports.handler = function(event, context) { event.response = {"claimsOverrideDetails":{"claimsToAddOrOverride":{"attribute_key2":"attribute_value2","attribute_key":"attribute_value"},"claimsToSuppress":["email"],"groupOverrideDetails":{"groupsToOverride":["group-A","group-B","group-C"],"iamRolesToOverride":["arn:aws:iam::XXXXXXXXXXXX:role/sns_callerA","arn:aws:iam::XXXXXXXXX:role/sns_callerB","arn:aws:iam::XXXXXXXXXX:role/sns_callerC"],"preferredRole":"arn:aws:iam::XXXXXXXXXXX:role/sns_caller"}}} console.log(event); context.done(null, event); }

User Migration Example: Migrate a User with an Existing Password

This example Lambda function migrates the user with an existing password and suppresses the welcome message from Amazon Cognito.

exports.handler = function(event, context) { if ( event.triggerSource == "UserMigration_Authentication" ) { // authenticate the user with your existing user directory service var user = authenticateUser(event.userName, event.request.password); if ( user ) { event.response.userAttributes = { "email": user.emailAddress, "email_verified": "true" }; event.response.finalUserStatus = "CONFIRMED"; event.response.messageAction = "SUPPRESS"; context.succeed(event); } else { context.fail("Bad password"); } } else if ( event.triggerSource == "UserMigration_ForgotPassword" ) { // Lookup the user in your existing user directory service var user = lookupUser(event.userName); if ( user ) { event.response.userAttributes = { "email": user.emailAddress, // required to enable password-reset code to be sent to user "email_verified": "true" }; event.response.messageAction = "SUPPRESS"; context.succeed(event); } else { context.fail("Bad password"); } } else { context.fail("Bad triggerSource " + event.triggerSource); } };