AWS Cognito Authentication in Reactjs

finite_diffidence

I have built applications using Firebase and React, and the procedure is pretty seamless.

Lately I have been required to use AWS Cognito, and it seems a bit of a pain to set up as the docs are not clear.

Firstly, how can I do user authentication using Cognito? I set up a user pool, with the following app client settings:

enter image description here

Now, I add the authorizer to my API as follows:

enter image description here

Now my question is, how do I use this with my frontend to sign in a user and make authenticated API calls?

There seem to be two different toolkits available:

  1. https://github.com/aws/aws-sdk-js
  2. https://github.com/aws-amplify/amplify-js

It is not clear at all for a beginner what to use, and how to get authentication working. Ideally I would use it like I do for firebase, and just have my frontend make an authentication call using the email and password, and in turn receiving a token of some sort (on success only) that can then be used to then make signed API calls.

Can someone please help with code examples?

ryandam

sorry for the confusion.

AWS Cognito Userpools act as an Identity Provider. It supports all User management (Sign Up, Sign In, Password reset, User deletion, etc). Cognito also supports Federated Identity (E.g., A User who already has an Google/Facebook account can sign in). In this case, Cognito talks to Google/Facebook using OAuth.

When I was learning about Cognito/JWT tokens, I created a simple JS/HTML to understand how it works. Since you asked for code, you can refer it - https://github.com/ryandam9/Cognito-tokens.

As per your screen shot, you already configured a Userpool - sls-notes-backend. Say, you configured the mandatory attribute as Email.

Step 0 - Initialize You get both userPoolId and appId when you create the user pool.

poolData = {
    UserPoolId: userPoolId,
    ClientId: appId
};

userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);

Step 1 - Signup a User using Email and Password - Say your UI already captured these details from the User and user clicked on 'Sign Up' button.

enter image description here

/**
 * Signup a User
 * @param e
 */
function addUser(e) {
    signupMessage.style.display = 'none';
    signupMessage.className = '';

    e.preventDefault();

    let name = document.getElementById('name').value.trim();
    let email = document.getElementById('signup-email').value.trim();
    let password = document.getElementById('signup-password').value.trim();

    if (name.length === 0 || email === 0 || password === 0) {
        return;
    }

    let attributeList = [
        new AWSCognito.CognitoIdentityServiceProvider.CognitoUserAttribute({
            Name: 'given_name', Value: name
        }),
    ];

    userPool.signUp(email, password, attributeList, null, function (err, result) {
        if (err) {
            signupMessage.innerText = err;
            signupMessage.style.display = 'block';
            signupMessage.className = 'alert alert-danger';
            return;
        }

        cognitoUser = result.user;
        console.log('user name is ' + cognitoUser.getUsername());

        // Show a text box to enter Confirmation code
        document.getElementById('signup-btn').style.display = 'none';
        document.getElementById('code-block').style.display = 'block';
        document.getElementById('confirm-user-btn').style.display = 'inline-block';
    });
}

If the signup is successful (It is valid Email and the Email does not yet exist in Userpools, a Confirmation code is sent to the Email provided. Next step is to, allow the user to enter the code and confirm his identity.

Step 3 - Confirm User

enter image description here

/**
 * Confirm the user by taking the Confirmation code.
 * @param e
 */
function confirmUser(e) {
    e.preventDefault();
    let verificationCode = document.getElementById('code').value;

    cognitoUser.confirmRegistration(verificationCode, true, function (err, result) {
        if (err) {
            signupMessage.innerText = err;
            signupMessage.style.display = 'block';
            signupMessage.className = 'alert alert-danger';
            return;
        }

        signupMessage.innerText = result;
        signupMessage.style.display = 'block';
        signupMessage.className = 'alert alert-success';
    });
}

If the User enters correct code, his identity is confirmed. At this point, An entry is made to the Userpool for this user. It looks like this. enter image description here

Step 4 - Authentication (Sign In) At this point, User registration is done. Its time to allow him to login. Please ignore the unnecessary code in the code below (the code that fetches and prints credentials, decoding part). If the authentication is successful, Cognito returns two types of Tokens to the application - ID Token and Access Token. These are valid only for this session and for this user only. More details here - https://ryandam.net/aws/19-cognito-userpools/index.html#0

/**
 * Signin user with Email and Password
 * @param e
 */
function authenticateUser(e) {
    e.preventDefault();

    let email = document.getElementById('signin-email').value;
    let password = document.getElementById('signin-password').value;

    if (email.length === 0 || password === 0 || userPool === null || userPool === undefined) {
        signinMessage.innerText = 'Fill in all fields!';
        signinMessage.style.display = 'block';
        signinMessage.className = 'alert alert-danger';
        return;
    }

    let authenticationData = {
        Username: email,
        Password: password,
    };

    let authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);

    let userData = {
        Username: email,
        Pool: userPool
    };

    let cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);

    cognitoUser.authenticateUser(authenticationDetails, {
            onSuccess: function (result) {
                signinMessage.innerText = 'Authentication Success!';
                signinMessage.style.display = 'block';
                signinMessage.className = 'alert alert-success';

                document.getElementById('token-section').style.display = 'block';
                document.getElementById('signin-btn').style.display = 'none';

                // Decode ID Token
                let idToken = result.idToken.jwtToken;
                document.getElementById('id-token').innerText = idToken;
                document.getElementById('decoded-id-token').appendChild(parseIdToken(idToken));

                // Decode Access Token
                let accessToken = result.getAccessToken().getJwtToken();
                document.getElementById('access-token').innerText = accessToken;
                document.getElementById('decoded-access-token').appendChild(parseAccessToken(accessToken));

                let cognitoUser = userPool.getCurrentUser();

                if (cognitoUser != null) {
                    cognitoUser.getSession(function (err, result) {
                        if (result) {
                            // Set the region where your identity pool exists (us-east-1, eu-west-1)
                            AWS.config.region = region;
                            AWS.config.update({region: region});

                            logins = {};
                            let key = 'cognito-idp.us-east-2.amazonaws.com/' + userPoolId;
                            logins[key] = result.getIdToken().getJwtToken();

                            // Add the User's Id Token to the Cognito credentials login map.
                            AWS.config.credentials = new AWS.CognitoIdentityCredentials({
                                IdentityPoolId: identityPoolId,
                                Logins: logins,
                            });

                            // Make the call to obtain credentials
                            AWS.config.credentials.get(function () {
                                // Credentials will be available when this function is called.
                                var accessKeyId = AWS.config.credentials.accessKeyId;
                                var secretAccessKey = AWS.config.credentials.secretAccessKey;
                                var sessionToken = AWS.config.credentials.sessionToken;
                            });

                            if (s3BucketName.length > 0)
                                listS3Bucket(s3BucketName);
                        }
                    });
                }
            },
            onFailure: function (err) {
                signinMessage.innerText = err;
                signinMessage.style.display = 'block';
                signinMessage.className = 'alert alert-danger';
            }
        }
    );
}

Step 5 - Invoking the API Endpoint you already created - Since you've already created an Authorizer using the Userpool and you're using Authorization as the header, you can invoke the End point from JS by passing the ID token as Authorization header. What happens is that, the token is validated by the authorizer. Since it is valid the user is able to invoke the API.**

I do not have JS code, you can test your API from CLI/Postman something like this:

enter image description here

Note AWS Amplify seems to be a wrapper for Cognito and other services. For instance, Amplify sets up User pool for you when you invoke its CLI commands. You can refer this code if you want to see how Amplify works with Flutter - https://github.com/ryandam9/Auth-flutter-aws-amplify.

I am still learning. I tried to be as accurate as possible.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

AWS Cognito as Django authentication back-end for web site

AWS Cognito API Authentication flow SDKs

Firebase authentication vs AWS Cognito

AWS iOS SDK Cognito Developer Authentication (Swift)

Integrating AWS Cognito with API for authentication

User Authentication (Signup & Login) on AWS with Lambda, Cognito or IAM

AWS Cognito error: Authentication delegate not set

AWS Cognito User Authentication

Flow for authentication when MFA required for user in AWS Cognito

Google Authentication fails with AWS Cognito Identity Pool on Android

Multi-Tenant Authentication with AWS Cognito

Checking if email is verified in aws cognito using AWS Amplify Authentication module

How to achieve certificate based authentication with AWS Cognito?

Authentication/Cognito SDK not working once deployed to AWS Lambda

How to include TOTP MFA in AWS Cognito authentication process

AWS Cognito for Django3 + DRF Authentication

How do AWS Cognito Authentication tokens refresh

AWS Cognito authentication with Bearer token

Custom Authentication flow with aws amplify cognito

AWS Cognito HTTP authentication

ios swift AWS cognito and Facebook Authentication

Authentication with Lambda and AWS Cognito

AWS Cognito Amplify Authentication and Angular UI Components

AWS API gateway authentication without using Cognito

Object is of type unknown with AWS Cognito authentication

Better User authentication?(aws cognito or Oauth2 or okta)

How to ignore MFA Authentication in AWS Cognito

AWS Cognito Pre authentication get user data

React Native authentication and Subscribtion with AWS Cognito UserPools