如何从Lambda中的回调函数返回json?

问题描述 投票:0回答:3

我正在尝试从Cognito回调函数返回登录状态,该函数是在NodeJS Lambda中编写的。但是,当我调用API时,响应继续加载,我收到警告错误。

这是我的代码:

'use strict';

global.fetch = require('node-fetch');
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');

module.exports.hello = async (event, context) => {
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: "Hello there"
    }),
  };

  // Use this code if you don't use the http event with the LAMBDA-PROXY integration
  // return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
};


module.exports.register = async (event, context, callback) => {

  let poolData =  {
      UserPoolId : 'xxxxx', // Your user pool id here
      ClientId : 'xxxxxxx' // Your client id here
  } // the user Pool Data

  let userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);

  let attributeList = [];

  let dataEmail = {
      Name : 'email',
      Value : '[email protected]'
  };

  let dataName = {
      Name : 'name',
      Value : 'Jack'
  };

  var dataPhoneNumber = {
      Name : 'phone_number',
      Value : '+94234324324234' // your phone number here with +country code and no delimiters in front
  };

  let attributeEmail = new AmazonCognitoIdentity.CognitoUserAttribute(dataEmail);
  let attributeName = new AmazonCognitoIdentity.CognitoUserAttribute(dataName);
  var attributePhoneNumber = new AmazonCognitoIdentity.CognitoUserAttribute(dataPhoneNumber);

  attributeList.push(attributeEmail);
  attributeList.push(attributeName);
  attributeList.push(attributePhoneNumber);

  userPool.signUp('[email protected]', 'H1%23$4jsk', attributeList, null, function(err, result){

    let data = {};

    if (err) {
      callback(null, {
          statusCode: 500,
          body: JSON.stringify({
            status: 'FAIL',
            message: err.message
          }),
        });
      } else {
        let cognitoUser = result.user;

        callback(null, {
          statusCode: 200,
          body: JSON.stringify({
            status: 'SUCCESS',
            message: '',
            data: {
              username: cognitoUser.getUsername(),
              id: result.userSub
            }
          }),
        });
      }
  })

  // Use this code if you don't use the http event with the LAMBDA-PROXY integration
  // return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
};

警告错误如下:

Serverless: Warning: handler 'register' returned a promise and also uses a callback!
This is problematic and might cause issues in your lambda.

Serverless: Warning: context.done called twice within handler 'register'!

serverless.yml

service: test-auth 
plugins:
  - serverless-offline

provider:
  name: aws
  runtime: nodejs8.10
  stage: dev
  region: us-east-1

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: message
          method: get
  register:
    handler: handler.register  
    events:
      - http:
          path: register
          method: post

任何帮助将不胜感激,提前致谢。

编辑(2019-04-01):

module.exports.register = (event, context) => {

  ...

  userPool.signUp('[email protected]', 'H1%23$4jsk', attributeList, null, function(err, result){

    // for testing purpose directly returning 
    return {
      statusCode: 500,
      body: JSON.stringify({
        status: 'FAIL',
        message: err.message
      })
    }

  })

};
javascript node.js callback aws-lambda amazon-cognito
3个回答
2
投票

那么错误是准确的。 asyncreturn包装你的promise。要么一直使用回调,例如:

global.fetch = require('node-fetch');
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');

// remove async
module.exports.register = (event, context, callback) => {

  ...

  // if you're using callback, don't use return (setup your callback to be able to handle this value as required) instead do:
  // calback({ message: 'Go Serverless v1.0! Your function executed successfully!', event })

  // Use this code if you don't use the http event with the LAMBDA-PROXY integration
  // return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
};

或者不使用回调,一直使用async/awaitPromise),如:

module.exports.register = async (event, context) => {

  ...

  // needs promise wrapper, when using with promise, you might want to break up your code to be more modular
  const mySignUp = (email, password, attributes, someparam) => {
    return new Promise((resolve, reject) => {
      userPool.signUp(email, password, attributes, someparam, function(err, result) {

        let data = {};

        if (err) {
          reject({
            statusCode: 500,
            body: JSON.stringify({
              status: 'FAIL',
              message: err.message
            }),
          });
        } else {
          let cognitoUser = result.user;

          resolve({
            statusCode: 200,
            body: JSON.stringify({
              status: 'SUCCESS',
              message: '',
              data: {
                username: cognitoUser.getUsername(),
                id: result.userSub
              }
            }),
          });
        }
      })
    });
  }

  // call the wrapper and return
  return await mySignUp('[email protected]', 'H1%23$4jsk', attributeList, null);

  // don't use double return
  // Use this code if you don't use the http event with the LAMBDA-PROXY integration
  // return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
};

现在register将返回promise。在代码的其他地方,你可以调用注册表:

var result = register();
result
  .then(data => console.log(data))
  // catches the reject from Promise
  .catch(err => console.error(err))

or in async/await function (Note: `await` is valid only inside `async` function)

async function someFunc() {
  try {
    var result = await register();
    // do something with result
    console.log(result);
  } catch (err) {
  // reject from Promise
    console.error(err)
  }
}

另请注意,此处不需要use strict,因为节点模块默认使用strict。


1
投票

它正是错误消息所指出的。

所有async函数都返回promise。 module.exports.register = async (event, context, callback) => {}

您还通过调用使用回调

callback(null, {
          statusCode: 500,
          body: JSON.stringify({
            status: 'FAIL',
            message: err.message
          }),
        });

而不是使用回调,只返回错误或有效的响应。


0
投票

您正在使用带回调的异步功能。

试试这种方式:

从异步函数中删除回调。

async (event, context)

并将返回修改为:

if (err) {
      return {
          statusCode: 500,
          body: JSON.stringify({
            status: 'FAIL',
            message: err.message
          })
        }
      }

并在函数调用上放置一个await

© www.soinside.com 2019 - 2024. All rights reserved.