AWS Cognito Lambda触发两次

时间:2019-01-18 07:25:36

标签: node.js amazon-web-services aws-lambda amazon-cognito

我正在使用AWS Lambda函数(使用nodejs)。

一旦APP向Cognito发送任何请求以注册用户。 然后,我设置了预注册触发器,以验证用户的客户并检查我们数据库中是否有可用的用户自定义属性。如果是,则返回错误,否则将新记录插入数据库并将事件返回给Cognito。

TimeoutInfo-5分钟。

它在请求中的某个时间发生,而不是总是发生。 RequestId为不同的。 (有时会触发3次,大多数时候会触发两次)

Lambda触发代码如下。

users / index.js

const handler = async (event, context) => {
  log.info('createUserLambda:start');
  // immediately return once the call back is called to avoid
  // lambda time out because of any open db connections
  context.callbackWaitsForEmptyEventLoop = false;
  return await preUserCreate(event);
};

exports.handler =处理程序; users / users.js

export const preUserCreate = async (event) => {
  log.info('preUserCreate:Start');
  let userAttributes = event.request.userAttributes;
  const currentDate = moment().utc().format('YYYY-MM-DD HH:mm:ss');
  try {
    let userParams = {
      'docStatus': 'VRF'
    };
    let docParams = [{
      'docNumber': userAttributes['custom:document_number'] ? userAttributes['custom:document_number'] : '',
      'createdDate': currentDate
    }];
    if (docParams.length && docParams[0].docNumber) {
      let documentExit = await getDocs(docParams[0].docNumber);
      if (documentExit.length) {
        log.info('preUserCreate:Error');
        throw new Error('Document number already exist.');;
      }
    }

    let documentRs = await insertDocument(docParams);
    userParams = {
      'did': documentRs[0].id,
      'id': event.userName,
      'createdDate': currentDate,
      'updatedDate': currentDate,
      ...userParams
    };
    let userRs = await insertUser([userParams]);
    if (docParams.length && docParams[0].docNumber) {
      let resultData = await getUserAccountFromAPI(docParams[0].docNumber);
      if (resultData) {
        let foramattedData = await formattedAccountsData(resultData, userRs[0].id, documentRs[0].id);
        await insertUserAccounts(foramattedData);
      }
    }
    log.info('preUserCreate:Success');
    event.response = {
      'autoConfirmUser': false,
      'autoVerifyPhone': false,
      'autoVerifyEmail': false
    };
    return event;
  } catch (error) {
    log.info('preUserCreate:Error', error);
    throw (error);
  }
}

2 个答案:

答案 0 :(得分:1)

您是否有机会在VPC中运行Lambda?我已经看到Cognito触发器在冷启动时在VPC中运行的类似行为。一旦lambda变热,问题就消失了

我的直觉是内部Cognito执行触发器的超时时间非常短,如果触发器未及时答复,它将自动重试。

我们最终不得不在触发器中添加逻辑以测试这种情况,以便避免重复写入数据库。

答案 1 :(得分:1)

之所以会发生这种情况,是因为集成Lambda的Cognito强制执行超时为5秒,因此无法更改。另外请注意,Cognito尝试(重新)调用该函数的最大次数为3次。

Customizing User Pool Workflows with Lambda Triggers部分中指出:

  

重要   Amazon Cognito同步调用Lambda函数。什么时候   调用时,您的Lambda函数必须在5秒内响应。如果有   否,Amazon Cognito重试该呼叫。尝试3次失败后,   该功能超时。此5秒超时值无法更改。

因此,为减少执行时间,值得考虑在可能的地方引入缓存。包括数据库连接等。

但是请注意,您几乎无法控制Lambda重复使用与重新启动的频率,因此您需要在预热时间方面牢记这一点。