Amazon Cognito
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

AWS Lambda 触发器示例

本部分提供了每种 AWS Lambda 触发器的代码示例。

注册前示例:自动确认用户

以下示例在服务启动新用户注册流程之前初始化。借助此 Lambda 函数,您可以添加自定义逻辑,以验证、筛选或限制可以注册的用户账户类型。例如,您可能只希望允许已受邀加入服务的用户注册。此示例使用 autoConfirmUser 标记指示是否向用户池自动确认用户。

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 } }

注册前示例:自动确认和自动验证用户

以下示例类似于示例 #1,但它会自动确认用户,并自动将用户的 emailphone_number 属性设置为已验证 (如果存在该属性)。

如果启用了别名,当设置了自动验证时,将为 phone_numberemail 创建别名。如果已存在具有相同电话号码的别名,则别名将移动到新用户,以前用户的 phone_number 将标记为未验证。电子邮件地址也是如此。如果这不是所需行为,您可以使用 ListUsers API 查看现有用户是否已经使用新用户的电话号码或电子邮件地址作为别名。

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); };

身份验证前示例

此示例函数限制来自特定应用程序客户端 ID 的用户进行身份验证。

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); };

示例事件参数:

{ "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": {} }

注册自定义消息示例

当服务要求应用程序向用户发送验证码时,系统会调用此 Lambda 函数自定义电子邮件或短信。

系统可以在多个时间点调用 Lambda 触发器:注册后;重新发送验证码时;忘记密码时;或验证用户属性时。响应包含电子邮件和 SMS 消息。消息必须包含代码参数 "####",该参数是发送给用户的验证码的占位符。

对于电子邮件,消息的最大长度为 20,000 个 UTF-8 字符,其中包括验证代码。可以在这些电子邮件中使用 HTML 标签。SMS 的最大长度为 140 个 UTF-8 字符,其中包括验证码。

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); };

示例事件参数:

{ "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>" } }

管理员创建用户的自定义消息示例

具有 CustomMessage_AdminCreateUser 触发器的自定义消息 Lambda 函数将返回用户名和验证码,所以消息正文中将包含 request.usernameParameterrequest.codeParameter

代码参数值 "####" 是临时密码的占位符,"username" 是向您的用户提供的用户名占位符。

对于电子邮件,消息的最大长度为 20,000 个 UTF-8 字符,其中包括验证代码。可以在这些电子邮件中使用 HTML 标签。SMS 的最大长度为 140 个 UTF-8 字符,其中包括验证码。

响应包含电子邮件和 SMS 消息。

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); };

示例事件参数:

{ "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>" } }

身份验证后示例

系统在用户成功进行身份验证后调用此函数。此示例函数在用户进行身份验证后登录到控制台。

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); };

示例事件参数:

{ "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": {} };

确认后示例

此示例发送一封电子邮件,通知用户他或她已得到确认。

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"); };

示例事件参数:

{ "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": {} }

定义身份验证质询示例

此示例针对身份验证定义一系列质询并发布质询令牌 (仅在成功完成所有质询后)。

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); }

创建身份验证质询示例

CAPTCHA 作为针对用户的质询而创建。CAPTCHA 图像的 URL 作为 captchaUrl 添加到公有质询参数中,并且预期答案添加到私有质询参数中。

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); }

验证身份验证质询响应示例

在本示例中,Lambda 函数检查用户对质询的响应是否与预期响应一致。如果用户的响应与预期响应一致,则 answerCorrect 参数设置为 true

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); }

令牌生成前示例:添加新声明并隐藏现有声明

此示例使用令牌生成前 Lambda 来添加新声明和隐藏现有声明。

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); }

令牌生成前示例:修改用户的组成员资格

此示例使用令牌生成前 Lambda 来修改用户的组成员资格。

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); }

用户迁移示例:迁移已有密码的用户

此示例 Lambda 函数迁移已有密码的用户,并隐藏 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); } };