Send cognito authentication as a promise is giving

2019-08-17 23:44发布

问题:

I'm developing a lambda function to login into Cognito, but I'm having problems to do it wait for my cognito authentication.

I tried to use the code just like it is in examples, passing a onSuccess and a onFailure function as parameter, but the function is complete without wait. Then, I tried to make a promise, just like I did sending SES email, but it give the message "Cannot read property 'promise' of undefined"

My code until now:

'use strict';

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

function criarResposta( statusCode, retorno ) {
    return {
        statusCode: statusCode,
        body: retorno
    };
}

module.exports.login = async (event) => {
    let enviar_promise = null;
    let nome_usuario = "::USER_NAME::";
    let senha_usuario = "::USER_PASSWORD::";

    let authentication_data = {
        Username : nome_usuario,
        Password : senha_usuario,
    };
    let authentication_details = new AmazonCognitoIdentity.AuthenticationDetails(authentication_data);
    let pool_data = { 
        UserPoolId : '::USER_POOL_ID::',
        ClientId : '::CLIENT_ID::'
    };
    let user_pool = new AmazonCognitoIdentity.CognitoUserPool(pool_data);
    let user_data = {
        Username : nome_usuario,
        Pool : user_pool
    };
    let cognito_user = new AmazonCognitoIdentity.CognitoUser(user_data);

    enviar_promise = cognito_user.authenticateUser( authentication_details ).promise();

    try {
        const dados = await enviar_promise;
        return criarResposta( 200, `{
            "message": "OK"
        }` );
    } catch (err) {
        console.error(err, err.stack);
        return criarResposta( 500, `{
            "message": "Erro interno"
        }` );
    }
};

EDIT

I've update my code according to an example and now it looks like it is waiting for response and it returns code 200 and {message: "OK"}, but it prints undefined on console.log( resultado );

Code:

'use strict';

global.fetch = require('node-fetch');
let AmazonCognitoIdentity = require('amazon-cognito-identity-js');
let AWS = require('aws-sdk');

function criarResposta( statusCode, retorno ) {
    return {
        statusCode: statusCode,
        body: retorno
    };
}

module.exports.login = async (event) => {
    let enviar_promise = null;
    let nome_usuario = "::USER_NAME::";
    let senha_usuario = "::USER_PASSWORD::";

    let authentication_data = {
        Username : nome_usuario,
        Password : senha_usuario,
    };
    let authentication_details = new AmazonCognitoIdentity.AuthenticationDetails(authentication_data);
    let pool_data = { 
        UserPoolId : '::USER_POOL_ID::',
        ClientId : '::CLIENT_ID::'
    };
    let user_pool = new AmazonCognitoIdentity.CognitoUserPool(pool_data);
    let user_data = {
        Username : nome_usuario,
        Pool : user_pool
    };
    let cognito_user = new AmazonCognitoIdentity.CognitoUser(user_data);

    try {
        let resultado = await cognito_user.authenticateUser( authentication_details );

        // let access_token = resultado.getAccessToken().getJwtToken();
        // let id_token = resultado.idToken.jwtToken;

        console.log( resultado );

        return criarResposta( 200, `{
            "message": "OK"
        }` );
    } catch (err) {
        console.error(err, err.stack);
        return criarResposta( 500, `{
            "message": "Erro interno"
        }` );
    }
};

EDIT 2

So, I made a pure nodejs code and it returns the access token and token id:

global.fetch = require('node-fetch');
let AmazonCognitoIdentity = require('amazon-cognito-identity-js');
let AWS = require('aws-sdk');

AWS.config.update({
    accessKeyId: '::VALOR::',
    secretAccessKey: '::VALOR::',
    region: 'us-east-2'
});

let enviar_promise = null;
let nome_usuario = "::VALOR::";
let senha_usuario = "::VALOR::";

let authentication_data = {
    Username : nome_usuario,
    Password : senha_usuario,
};
let authentication_details = new AmazonCognitoIdentity.AuthenticationDetails(authentication_data);
let pool_data = { 
    UserPoolId : '::VALOR::',
    ClientId : '::VALOR::'
};
let user_pool = new AmazonCognitoIdentity.CognitoUserPool(pool_data);
let user_data = {
    Username : nome_usuario,
    Pool : user_pool
};
let cognito_user = new AmazonCognitoIdentity.CognitoUser(user_data);

cognito_user.authenticateUser(authentication_details, {
    onSuccess: function (result) {
        let accessToken = result.getAccessToken().getJwtToken();
        let idToken = result.idToken.jwtToken;

        console.log( accessToken );
        console.log( idToken );
    },
    onFailure: function(err) {
        console.log(err);
    },
});

I think the problem is in try to send authenticateUser as a promise, but I don't know how to make lambda wait my request without it

回答1:

'use strict';

global.fetch = require('node-fetch');
let AmazonCognitoIdentity = require('amazon-cognito-identity-js');
let AWS = require('aws-sdk');

function criarResposta( statusCode, retorno ) {
    return {
        statusCode: statusCode,
        body: retorno
    };
}

module.exports.login = async (event) => {
    let enviar_promise = null;
    let nome_usuario = "::USER_NAME::";
    let senha_usuario = "::USER_PASSWORD::";

    let authentication_data = {
        Username : nome_usuario,
        Password : senha_usuario,
    };
    let authentication_details = new AmazonCognitoIdentity.AuthenticationDetails(authentication_data);
    let pool_data = { 
        UserPoolId : '::USER_POOL_ID::',
        ClientId : '::CLIENT_ID::'
    };
    let user_pool = new AmazonCognitoIdentity.CognitoUserPool(pool_data);
    let user_data = {
        Username : nome_usuario,
        Pool : user_pool
    };
    let cognito_user = new AmazonCognitoIdentity.CognitoUser(user_data);

    try {
        let resultado = await cognito_user.authenticateUser( authentication_details ).promise();

        // let access_token = resultado.getAccessToken().getJwtToken();
        // let id_token = resultado.idToken.jwtToken;

        console.log( resultado );

        return criarResposta( 200, `{
            "message": "OK"
        }` );
    } catch (err) {
        console.error(err, err.stack);
        return criarResposta( 500, `{
            "message": "Erro interno"
        }` );
    }
};



回答2:

After more search, I found it is possible to declare the lambda function differently and use a callback. It works fine for me.

Code:

'use strict';

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

module.exports.autenticacao = (event, context, callback) => {
    const dados_requisicao = JSON.parse( event.body );

    let authentication_data = {
        Username : dados_requisicao.usuario,
        Password : dados_requisicao.senha,
    };
    let authentication_details = new AmazonCognitoIdentity.AuthenticationDetails(authentication_data);
    let pool_data = { 
        UserPoolId : '::VALOR::',
        ClientId : '::VALOR::'
    };
    let user_pool = new AmazonCognitoIdentity.CognitoUserPool(pool_data);
    let user_data = {
        Username : dados_requisicao.usuario,
        Pool : user_pool
    };
    let cognito_user = new AmazonCognitoIdentity.CognitoUser(user_data);

    cognito_user.authenticateUser(authentication_details, {
        onSuccess: function (result) {
            let access_token = result.getAccessToken().getJwtToken();
            let id_token = result.idToken.jwtToken;

            callback(undefined, {
                statusCode: 200,
                body: JSON.stringify({
                    message: "OK",
                    accessToken: access_token,
                    idToken: id_token
                }),
            });
        },
        onFailure: function(err) {
            callback({
                statusCode: 500,
                body: JSON.stringify({
                    message: "Erro interno"
                }),
            });
        },
    });
};