Amplify-js: Can't seem to authenticate with Cognito

Created on 3 Jul 2018  路  16Comments  路  Source: aws-amplify/amplify-js

I'm not sure if it's a bug, but I've been trying to incorporate Cognito authentication into my React based project and getting an error that I can't make sense out of it. My code is based on examples given in NPM page. This is what it looks like :

import { CognitoUserPool, CognitoUser, AuthenticationDetails } from 'amazon-cognito-identity-js';    
var authenticationData = {
    Username : 'username',
    Password : 'password',
};
var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);
var poolData = {
    UserPoolId : '...', // Your user pool id here
    ClientId : '...' // Your client id here
};
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
var userData = {
    Username : 'username',
    Pool : userPool
};
var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
    onSuccess: function (result) {
               console.log('Successfully logged!');
            }
        });
    },

    onFailure: function(err) {
        console.log(JSON.stringify(err));
    },

});

I have created a user pool and added an app client. I have also enabled identity provider for app client. However, my code fails to authenticate with error {"code":"NetworkError","name":"Error","message":"Network error"}. Since my project is still hosted on localhost, I have installed CORS plug-in for firefox, but that doesn't resolve the issue. Is that an issue with Localhost?

Webpack 3
React 0.14.9

Auth Service Team investigating pending-close-response-required

Most helpful comment

In your Attributes setting, leave them uncheck unless you really need some. It fixed problem
Object {
"code": "NetworkError",
"message": "Network error",
"name": "Error",
}
screen shot 2018-07-05 at 01 15 54

All 16 comments

In your Attributes setting, leave them uncheck unless you really need some. It fixed problem
Object {
"code": "NetworkError",
"message": "Network error",
"name": "Error",
}
screen shot 2018-07-05 at 01 15 54

@toanphan0303 Thanks, it does get rid of that error. For anyone who's been following the issue, I just want to let you know that it isn't the only thing preventing my code from working. I have created a test user manually using Cognito console. If you create user with the console. you need to implement newPasswordRequired callback. Otherwise, you would get "Unknown error exception" which means nothing at all to me or anyone. Inside the callback, you need to reset the password with a new one. Otherwise, you would get another not-much-sense-error - "Unknown error". If you follow those steps, your authentication should work just fine.

@toanphan0303 Hi, I'm facing the same error although I changed the attribute settings as suggested by you. I'm facing when I use userPool.signUp

Have also just come across this error. Changing the attribute settings hasn't solved it and there doesn't seem to be any mention of it anywhere else online - would be helpful if the error in question gave any hint at what is actually wrong rather than being so generic

We're getting the same error, albeit inconsistently throughout our user pool. We don't want to have to change those attributes since we want our application to allow login with email and not with username.

Same error, makes no sense as to why. Very frustrating.

Similar issue for me, I am able to create a user through a lambda function, once that user Verifies their email address, I see everything looks good in the userpool. Now I want the user to request an accessToken which I will require for API gateway Access, following AWS Cognito blogs, this looks like the correct way to do things, however my lambda times out and I get no logs once I get to cognitoUser.authenticateUser. I'm not sure what is wrong, am I misunderstanding something?

Note: I am not leveraging a UI, all of this is happening on the backend through lambdas

'use strict';

//AWS Dependencies for Cognito and AWS SDK
var AmazonCognitoIdentity = require('amazon-cognito-identity-js');

//Include Custom Modules
exports.handler = (event, context, callback) => {

    // configure the authentication credentials
    var authenticationData = {
        Username: event.emailAddress,
        Password: event.password
    };
    // init Cognito auth details with auth data
    var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);

    // // get the pool data from the response
    var poolData = {
        UserPoolId: process.env['COGNITO_USER_POOL_ID'], //userPoolLookup.userPoolId,
        ClientId: process.env['COGNITO_APP_CLIENT_ID'] //userPoolLookup.client_id
    };
    // construct a user pool object
    var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
    // create object with user/pool combined
    var userData = {
        Username: event.emailAddress,
        Pool: userPool
    };


    // authenticate user to in Cognito user pool
    var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
    console.log("cognitoUser :: ", cognitoUser);
    cognitoUser.authenticateUser(authenticationDetails, {
        onSuccess: function(result) {
            // get the ID token
            console.log(":: In Success :: ");
            var idToken = result.getIdToken().getJwtToken();
            var AccessToken = result.getAccessToken().getJwtToken();
            let authResponse = {
                token: idToken,
                access: AccessToken
            }
            console.log("authResponse:: ", authResponse);

            //callback(null, authResponse);
        },
        onFailure: function(err) {
            console.log("onFail", err);
        }
    });
    console.log("AFTER cognitoUser :: ", cognitoUser);
};

I figured it out in my case, I was using it in an asp.net core project (which I am new to) and I was including the source sdk javascript file in the header (layout.cshtml), which somehow gets included on the page AFTER your page level code. So the reference was not above. Whats weird is that when I debugged my code, it would step through the sdk code just fine (indicating it indeed had a reference to the sdk after all.), but still fail with the same error. When I made sure I was writing my page level javascript AFTER the included sdk source declaration, everything worked fine.

Again, just to be completely clear, the error I was getting before verifying the sdk was included above my code was: {"code":"NetworkError","name":"Error","message":"Network error"}

So my issue was cognitoUser.authenticateUser takes awhile to fetch my token so all I needed to do was increase my lambda timeout. I'm a little surprised to learn that 3 seconds is not enough to get me a jwtToken.

Hi, @idurant , I am using the same approach to sign up and login user through lambda functions(Written in node) and exposed through API gateway. everything works as expected I am able to get the token on UI.
But for further operation like.
Update Attributes
Delete Attributes
Change a Password
Get the Current User
Javascript cognito doc

I will need cognitoUser to perfirm these operations.
But on UI I only have Token return on authenticating(through lambda) with cognito pool. How can I get cognitoUser(in my lambda) based on the Token Received on UI.

I am getting the cognito user though environment variables in the lambda. I set the appClientID and the cognitoUserPoolID based on the information found in Cognito. For my use case I only have 1 user pool so setting the environment variable was enough.

A second take on your question:

If you want cognito user its simply the function below

var userData = { Username: event.emailAddress, Pool: userPool }; /*authenticate user to in Cognito user pool*/ var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);

with the cognitoUser you can call the function below

cognitoUser.authenticateUser(authenticationDetails, { onSuccess: function(result) { console.log("Auth User Result: ", result); } callback(null, authResponse); }

The result that is being console logged has aud: which is the app client ID and iss: which is the cognito url with /poolID at the end

Hope this helps

Hi @idurant, Thank you for the quick response.
The code you have mentioned I am doing exactly same in my lambda function. on successful login I am returning (idToken, AccessTokan, and Refresh token) to UI. I am able be login and signup through my lamda function written in Node.

To secure my API gateways I have created an authorizer which authorises the Request.
User send the Token in header while calling my API and Authoriser check the Token and give access only if the token is Valid.

Here are Problem I am facing.

1.) The Token Expires in one hour. What is the best way to refresh the Token with Refresh Token.(As of now I am thinking to write custom authoriser to refresh the Token if it expires). (I do not want to use Client SDK to refresh it As I have multiple UI clients (Web, iOS and Android and I do not want handle this separately))
---- Please share your thoughts on this----

2.)The Code to login, signup and Forgot password, add/Edit/delete Attribute,change Password, global signout to perform any of the operation we need cognitoUser object.

There are two way to get cognitoUser.

first by Authenticaction (which expects username and Password)
var authenticationData = { Username : 'username', Password : 'password', }; var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData); var poolData = { UserPoolId : 'us-east-1_TcoKGbf7n', ClientId : '4pe2usejqcdmhi0a25jp4b5sh3' }; var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData); var userData = { Username : 'username', Pool : userPool }; var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);

Second by Retrieve the current user from local storage
var data = { UserPoolId : 'us-east-1_Iqc12345', ClientId : '12345du353sm7khjj1q' }; var userPool = new AmazonCognitoIdentity.CognitoUserPool(data); var cognitoUser = userPool.getCurrentUser();

Neither of them is suitable in my case as I am handling everything on server (Lambda in NodeJS)

Is there any way create cognitoUser Object with the help of token(So that Client Only send the Token from UI and we can create cognitoUser object and get the stuff done).

3.) What would be the best way to Align Multi-factor Authentication with the above mentioned architecture (using Cognito SDK on server(in Lambda Function))

Thanks in Advance.

From my understanding if you have the user validate with the refresh token it will handle the refresh automatically.

I had trouble finding out how to access the refresh token but refreshToken.token does the trick. You will have to look at the documentation for the different use cases for idToken, accessToken, and refreshToken. I'm interested in knowing you're finding.
https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html

result refers to the onSuccess callback parameter
var accessToken = result.getAccessToken().getJwtToken(); var idToken = result.getIdToken().getJwtToken(); var refreshToken = result.refreshToken.token;

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

This issue has been automatically closed because of inactivity. Please open a new issue if are still encountering problems.

Was this page helpful?
0 / 5 - 0 ratings