-->

AWS - nodejs SDK - CognitoIdentityServiceProvider.

2020-07-13 23:38发布

问题:

I'm trying to get authentication working through my API using AWS Cognito with a user pool. I have a user created through an AWS Cognito User Pool and I'm trying to log in with the user.

The error I'm getting is CredentialsError: Missing credentials in config. Specifically it was telling me that I needed an IdentityPoolId. But I can't seem to find this IdentityPoolId in my AWS console. Where the heck do I get this from for my user pool? All I see is a Pool id and a Pool ARN.

Relevant source code:

var aws = require('aws-sdk');
aws.config.update({
    region: 'us-east-1',
    credentials: new aws.CognitoIdentityCredentials({
        IdentityPoolId: '???'
    })
});


var authUser = function(params, callback)
{
    if (!params || !params.Email || !params._password)
    {
        callback(new Error('Invalid parameters.'));
        return false;
    }

    var cognito = new aws.CognitoIdentityServiceProvider();

    var authParams = {
        AuthFlow: 'USER_SRP_AUTH', // not sure what this means...
        ClientId: conf.AWSConfig.ClientId,
        AuthParameters: {
            Username: params.Email,
            Password: params._password
        }
    };

    cognito.initiateAuth(authParams, function(err, data)
    {
        if (err)
        {
            console.log('Error details: ' + util.inspect(err));
            callback(err);
            return false;
        }
        callback(null, {success: true, data: data});
    });
}

For the authParams object, I'm not sure what the AuthFlow should be. Looking at http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html#initiateAuth-property it seemed like USER_SRP_AUTH was what I should likely be using.

Edit:

I believe I may have found where to get my IdentityPoolId. I viewed my Federated Identities section and added in the appropriate User Pool under the Authentication Providers section while editing the identity pool.

I associated the Authentication Provider for Cognito to my User Pool that I created by entering the User Pool ID and App Client ID for that user pool. Now with the same code using that Identity pool ID I'm getting the error CredentialsError: Missing credentials in config. It says Unauthorized access is not supported for this identity pool. OK... I'm trying to authorize the user... Do I need to create an Unauthenticated role so that users can authenticate when they're not authenticated? That seems silly if that's what I need to do.

Edit 2:

I should also note that I was able to log in and get an AccessToken as well as an IdToken and RefreshToken using the Javascript SDK (not nodejs). I did this without the need of an IdentityPoolId. The only things I needed were a UserPoolId and a ClientId.

var authenticateUser = function(onSuccessCallback)
{
    var authData = {
        Username: getUserName(), // gets username from an html text field
        Password: getPassword()  // gets password from an html password field
    };

    var authDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authData);

    var cognitoUser = getCognitoUser();

    cognitoUser.authenticateUser(authDetails,
    {
        onSuccess: function(result)
        {
            console.log('access token: ' + result.getAccessToken().getJwtToken());
            console.log('idToken: ' + result.idToken.jwtToken);
            console.log(result);

            if (onSuccessCallback && typeof(onSuccessCallback) == 'function')
            {
                onSuccessCallback(cognitoUser);
            }
        },
        onFailure: function(err)
        {
            // UserNotConfirmedException: User is not confirmed.
            console.log('authError');
            alert(err);
        }
    });
}

回答1:

Turns out that initiateAuth was not at all what I wanted to be doing. I was also missing an npm package called amazon-cognito-identity-js. After installing that I updated my code as follows:

var authUser = function(params, callback)
{
    if (!params || !params.Email || !params._password)
    {
        callback(new Error('Invalid parameters.'));
        return false;
    }

    var poolData = {
        UserPoolId: conf.AWSConfig.UserPoolId,
        ClientId: conf.AWSConfig.ClientId
    };

    var userPool = new aws.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
    var authData = {
        Username: params.Email,
        Password: params._password
    };

    var authDetails = new aws.CognitoIdentityServiceProvider.AuthenticationDetails(authData);
    var userData = {
        Username: params.Email,
        Pool: userPool
    };

    var cognitoUser = new aws.CognitoIdentityServiceProvider.CognitoUser(userData);

    cognitoUser.authenticateUser(authDetails, {
        onSuccess: function(result)
        {
            callback(null, {success: true, data: result});
        },
        onFailure: function(err)
        {
            console.log('authUser error: ' + util.inspect(err));
            callback(err);
        }
    });
}

I am now successfully getting a response with tokens! Hooray!



回答2:

Just set up the Authentication credentials with AWS and use the config options.

const settings = Settings.GetSettings('Cognito');
const auth = {
  region: settings['region'],
  apiVersion: settings['api-version'],
  accessKeyId: settings['access-key-id'],
  secretAccessKey: settings['secret-access-key']
};
const CognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider(auth);
var config = {
  UserPoolId: settings['user-pool-id'],
  Username: guid
};
CognitoIdentityServiceProvider.adminDeleteUser(config, function (err, data) {
  if (err) {
    reject(err);
  } else {
    resolve(data);
  }
});