繁体   English   中英

如何从Lambda内的回调function返回json?

[英]How to return json from callback function within the Lambda?

我正在尝试从 Cognito 回调 function 返回登录状态,这是在 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 : 'test@gmail.com'
  };

  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('test@gmail.com', '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'!

无服务器.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('test@gmail.com', 'H1%23$4jsk', attributeList, null, function(err, result){

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

  })

};

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

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('test@gmail.com', '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的节点模块使用严格的默认这里不需要。

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

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

您还通过调用使用回调

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

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

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

试试这种方式:

从异步函数中删除回调。

async (event, context)

并将返回修改为:

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

await函数调用。

如果它帮助其他人抓住这个,你可以在返回中添加标题:

return {
      statusCode: 200,
      headers: {"Content-Type": "application/json"},
      body: JSON.stringify(response.data)
    };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM