Front-End Web & Mobile

Accessing Your User Pools using the Amazon Cognito Identity SDK for JavaScript

Introduction

In April, we launched the beta version of a new Amazon Cognito feature called Your User Pools. Among other functionality, the User Pools feature makes it easy for developers to add sign-up and sign-in functionality to web apps. AWS Mobile SDKs for Android, JavaScript, and iOS are available with this beta launch. In this blog post we will show you how to access the new functionality by using the Amazon Cognito Identity SDK for JavaScript.

Integrating your user pool into your web app

To integrate this new feature into your app, follow the instructions in the Announcing Your User Pools in Amazon Cognito blog post to create your user pool. Note that Generate client secret must be unchecked when creating a web app; the Amazon Cognito Identity SDK for JavaScript doesn’t support apps that have a client secret simply because the client secret could be easily viewed in your code.

Also for brevity, in this blog post we will focus on the functionality provided by the Amazon Cognito Identity SDK for JavaScript. Information about dependencies and setup instructions can be found in the GitHub repository.

Using your user pool in your web app

The first step for interacting with the new feature is to create a CognitoUserPool object by providing a UserPoolId and a ClientId. As mentioned, the SDK does not support the app client secret. If you configure your user pool app client with an app client secret, the SDK will throw exceptions.

Throughout the examples in this post, we will use the userPool object, the userData object (containing the user pool) and the username object, as shown in the following.

AWSCognito.config.region = 'us-east-1';

var poolData = {
    UserPoolId : '...', // your user pool id here
    ClientId : '...' // your client id here
};
var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
var userData = {
    Username : '...', // your username here
    Pool : userPool
};

After creating a user pool object, users can be signed up for the application. The necessary information about the user can be collected through the web UI and used to populate CognitoUserAttribute objects that are passed in the signUp call.

var attributeList = [];
    
var dataEmail = {
    Name : 'email',
    Value : '...' // your email here
};
var dataPhoneNumber = {
    Name : 'phone_number',
    Value : '...' // your phone number here with +country code and no delimiters in front
};
var attributeEmail = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserAttribute(dataEmail);
var attributePhoneNumber = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserAttribute(dataPhoneNumber);

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

var cognitoUser;
userPool.signUp('username', 'password', attributeList, null, function(err, result){
    if (err) {
        alert(err);
        return;
    }
    cognitoUser = result.user;
    console.log('user name is ' + cognitoUser.getUsername());
});

After signing up, the user needs to confirm the sign-up by entering a code sent either through SMS or email (based on the user pool settings). Alternatively, you can use a PreSignUp AWS Lambda function to automatically confirm your users. To confirm sign-up, you must collect the code (‘123456’ in the following example) received by the user and use it as follows:

cognitoUser.confirmRegistration('123456', true, function(err, result) {
    if (err) {
        alert(err);
        return;
    }
    console.log('call result: ' + result);
});

The registration code can be resent by using the resendConfirmationCode method of a cognitoUser object. This is an unauthenticated call and only the username, the client ID, and the user pool information are needed.

A confirmed user can authenticate to obtain a session. The session contains an ID token that contains user claims, an access token that is used internally to perform authenticated calls, and a refresh token that is used internally to refresh the session after it expires each hour. For more information about tokens, see Using Tokens with Amazon Cognito Identity User Pools in the Amazon Cognito Developer Guide. When authentication is successful, the onSuccess callback is called. If authentication fails, the onFailure callback is called. If authentication requires MFA, the mfaRequired callback is called. You must invoke sendMFACode on the cognitoUser object. The verification code that is received must be passed and the user is finally authenticated.

var authenticationData = {
    Username : '...', // your username here
    Password : '...', // your password here
};
var authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);

var cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
    onSuccess: function (result) {
        console.log('access token + ' + result.getAccessToken().getJwtToken());
    },

    onFailure: function(err) {
        alert(err);
    },
    mfaRequired: function(codeDeliveryDetails) {
        var verificationCode = prompt('Please input verification code' ,'');
        cognitoUser.sendMFACode(verificationCode, this);
    }
});

After authenticating, a user can perform authorized operations such as, retrieve user attributes, verify user attributes (such as an unverified email address), delete user attributes, update user attributes, change the user password, and delete the user’s account. For user pools that have an MFA setting of optional, users can enable or disable MFA just for themselves, at a user level. Signing out from the application clears the local user session so the user must authenticate again to establish a new session.

If users forget their passwords, they can initiate a forgotten password flow. A code will be sent to the user. The user uses this code together with a new password to complete the flow.  The relevant call is forgotPassword on a cognitoUser object that is unauthenticated; the relevant callbacks can be seen in the following.

cognitoUser.forgotPassword({
    onSuccess: function (result) {
        console.log('call result: ' + result);
    },
    onFailure: function(err) {
        alert(err);
    },
    inputVerificationCode() {
        var verificationCode = prompt('Please input verification code ' ,'');
        var newPassword = prompt('Enter new password ' ,'');
        cognitoUser.confirmPassword(verificationCode, newPassword, this);
    }
});

If you want to work with other AWS services, you must first create a federated identity pool. After you create this identity pool, you can get AWS credentials by passing the identity pool ID and the ID token (obtained earlier) when authenticating. The following example shows how to populate IdentityPoolId and pass the ID token through the Logins map.

AWS.config.credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'us-east-1:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
    Logins: {
        'cognito-idp.us-east-1.amazonaws.com/us-east-1_XXXXXXXXX': result.getIdToken().getJwtToken()
    }
});

AWS.config.credentials.get(function(err){
    if (err) {
        alert(err);
    }
});

More examples and an overview of the code can be found in the GitHub repository. We welcome your feedback on this feature. You can reach us by creating an issue in the GitHub repository or posting to the Amazon Cognito forums.