添加了来自 Lambda 的 AWS Cognito adminCreateUser 重复用户名

AWS Cognito adminCreateUser from Lambda duplicated username added

我正在尝试从 lambda nodejs 添加一个新用户,但每次我尝试创建一个用户时,它都会在 Cognito 中添加它两次并得到以下错误。

如有任何意见或建议,我们将不胜感激。

这是我的 Lambda 测试

var AWS = require('aws-sdk');

AWS.config.update({
    region: 'ca-central-1',
    credentials: new AWS.CognitoIdentityCredentials({
        IdentityPoolId: IdentityPoolId,
    })
});

const cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider(
    {
        apiVersion: '2016-04-18',
        region: "ca-central-1",
        credentials: AWS.Credentials()
    }
);

module.exports.getCongito = getCongito;

async function getCongito() {
    
    var info = {
        UserPoolId: UserPoolId.prod,
        Username: 'test@gmail.com',
        TemporaryPassword: "Password1@#",

        UserAttributes: [
             {
                Name: 'name', /* required */
                Value: 'Name1' 
            },
             {
                Name: 'email', /* required */
                Value: 'test@gmail.com'
            },
             {
                Name: 'email_verified', /* required */
                Value: 'true'
            }
        ]
    }

    var params = {
        UserPoolId: info.UserPoolId, /* required */
        Username: info.Username,
        // TemporaryPassword: info.TemporaryPassword,/* required */
        DesiredDeliveryMediums: ["EMAIL"],
        UserAttributes: info.UserAttributes,
        ForceAliasCreation: false
        // 
        
    };

    await cognitoidentityserviceprovider.adminCreateUser(params, function (err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else console.log(data);           // successful response
    }).promise();

}

这是我的预注册 lambda,以避免重复 email/username

'use strict';

const AWS = require('aws-sdk');
const cognitoIdp = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18'});

exports.handler = function(event, context) {
  console.log(JSON.stringify(event));

  // check if email is already in use
  if (event.request.userAttributes.hasOwnProperty('email')) {
    const email = event.request.userAttributes.email;
    
    const params = {
      UserPoolId: event.userPoolId,
      Filter: 'email = "' + email + '"',
    };
    
    cognitoIdp.listUsers(params).promise()
    .then (results => {
      console.log(JSON.stringify(results));
      // if the usernames are the same, dont raise and error here so that
      // cognito will raise the duplicate username error
      if (results.Users.length > 0 && results.Users[0].Username !== event.userName) {
        console.log('Duplicate email address in signup. ' + email);
        context.done(Error('A user with the same email address exists'));
      }
     
      context.done(null, event);
    })
    .catch (error => {
      console.error(error);
      context.done(error);      
    });
  }
};

这是我在 运行 时得到的,当我转到 Cognito 用户池时,我看到了两个用户:

{
  "errorType": "InvalidParameterException",
  "errorMessage": "Alias entry already exists for a different username",
  "trace": [
    "InvalidParameterException: Alias entry already exists for a different username",
    "    at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:52:27)",
    "    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)",
    "    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)",
    "    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)",
    "    at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)",
    "    at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)",
    "    at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10",
    "    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)",
    "    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)",
    "    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)"
  ]
}

谢谢,

一些事情...当您将电子邮件设置为登录别名时,cognito 会强制它是唯一的。无需重复检查。

你的问题的根源是你传递了一个回调函数,然后把它变成了一个承诺。

await cognitoidentityserviceprovider.adminCreateUser(params, function (err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else console.log(data);           // successful response
    }).promise();

只需使用承诺。

下面是一个实现。我稍微清理了你的代码。

const AWS = require('aws-sdk');

/**
 * Grab the user pool id and region from environment variables
 */
const { 
    USER_POOL_ID = 'ca-central-1_xxxxxxxxx',
    AWS_REGION = 'ca-central-1'
} = process.env

/**
 * Set the AWS region
 */
AWS.config.update({
    region: AWS_REGION
});

/**
 * Create the Cognito IDP client
 */
const cognito = new AWS.CognitoIdentityServiceProvider();


/**
 * Create a test user for a given email
 * @param {string} email email to use for creating a test user. Defaults to 'test@example.com'
 */
 module.exports.createTestUser = async function createTestUser(email = 'test@example.com') {

    const params = {
        UserPoolId: USER_POOL_ID,
        Username: email,
        DesiredDeliveryMediums: ["EMAIL"],
        UserAttributes:  [
            {
               Name: 'name',
               Value: 'Test User' 
           },
            {
               Name: 'email',
               Value: email
           },
            {
               Name: 'email_verified',
               Value: 'true'
           }
       ]
    };

    const result = await cognito.adminCreateUser(params).promise()
    console.log(JSON.stringify(result, undefined, 2))
    return result
}