Engineering@ZenOfAI
May 31 · 7 min read

You could now use Amazon Cognito to easily add user sign-up and sign-in to your mobile and web apps. Your user pool in Amazon Cognito is a fully managed user directory that could scale to hundreds of millions of users, so you don’t have to worry about building, securing, and scaling a solution to handle user management and authentication.

When it comes to Cognito there are two main entities.

  1. User pools
  2. Identity pools

User pools is an identity provider. You could use this to authenticate users to your mobile app, website and manage users.

Identity pools are used to authorize users to give access to AWS resources such as IAM, S3, and etc.


Setting up User pool

First login to your AWS account and go to Cognito section. If you don’t have an AWS account yet, create a free account which will be free for a year. Then go to Cognito section and then create a user pool.

  1. Give a name for the pool. Let’s go with the step through settings.

2. Select how you want to authenticate users using either email, phone or both. For now, I’ll go with an email address. Next section we could select which attribute we need while signing up. We could even add custom attributes and I’m not gonna add any custom attributes.

Note: Once you create a Userpool you can’t change how users sign in, you can’t change the required attributes or delete any custom attributes.

3. Define password and signup criteria.

4. Define multi-factor authentication settings. I’m just going to leave it disabled for this demo.

5. If you want you could customize your email messages. So when a user signs-up he will get an email to confirm his account. You could customize that message here.

6. Add any tags you want to the user pool.

7. Define if you want to remember user devices or not.

8. In here you have to click on Add an app client and create the app client. The app client generates an app client Id and it’s needed to access the pool from application code. You should uncheck the Generate client secret option since Javascript SDK doesn’t support client secret for now.

9. If you want to execute any defined lambda functions at a certain point of auth flow, you could specify those here. If not just skip it.

10. Finally, review settings and create the pool.

That’s about it. Now note down the pool region, pool id and app client id. When you click on created pool overview section you could retrieve pool id, if you go to app clients, you could retrieve the app client id. You are going to need those for upcoming steps.


Integrating Cognito with web application

So here we learn how to use Cognito with my small web application in which users could sign up using a verified email via verification code sent to their email. If they log in with the valid credentials, only then they could see a secret web page.

It is a static web application where I’m gonna store my files in S3 bucket. Amazon S3 is a public cloud storage resource available on AWS.

We need some dependency files for our application which are:

  1. jQuery
  2. Cognito SDK(Download the webpage and store it with .js file)
  3. Bootstrap css and js (optional)

Below is the configuration file.

var poolData = {
UserPoolId: 'your userpool id',
ClientId: 'your client id'
};

The below code is a javascript file with functions in it.

var UserAPP = window.UserAPP || {};

(function scopeWrapper($) {

var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);

UserAPP.checkLogin = function (redirectOnRec, redirectOnUnrec) {
var cognitoUser = userPool.getCurrentUser();
if (cognitoUser !== null) {
if (redirectOnRec) {
window.location = '/Secret.html';
}
} else {
if (redirectOnUnrec) {
window.location = '/';
}
}
};

UserAPP.login = function () {
var username = $('#username').val();
var authenticationData = {
Username: username,
Password: $('#password').val()
};

var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);
var userData = {
Username: username,
Pool: userPool
};
var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function () {
window.location = '/Secret.html';
},
onFailure: function (err) {
alert(err);
}
});
};

UserAPP.logout = function () {
var cognitoUser = userPool.getCurrentUser();
cognitoUser.signOut();
window.location = '/';
};

UserAPP.signup = function () {
var username = $('#username').val();
var password = $('#password').val();
var email = new AmazonCognitoIdentity.CognitoUserAttribute({
Name: 'email',
Value: $('#email').val()
});

userPool.signUp(username, password, [email], null, function (err, result) {
if (err) {
alert(err);
} else {
window.location = '/confirm.html#' + username;
}
});
};

UserAPP.confirm = function () {
var username = location.hash.substring(1);
var cognitoUser = new AmazonCognitoIdentity.CognitoUser({
Username: username,
Pool: userPool
});
cognitoUser.confirmRegistration($('#code').val(), true, function (err, results) {
if (err) {
alert(err);
} else {
window.location = '/';
}
});
};

UserAPP.resend = function () {
var username = location.hash.substring(1);
var cognitoUser = new AmazonCognitoIdentity.CognitoUser({
Username: username,
Pool: userPool
});
cognitoUser.resendConfirmationCode(function (err) {
if (err) {
alert(err);
}
})
};

}(jQuery));

We shall import all dependency files in our HTML files. We have 4 HTML files which call different functions from above js file.

index.html

<div class="container center-block">
<form>
<div class="form-group">
<label ref="username">Username:</label>
<input id="username" type="text" maxlength="20"/>
</div>
<div class="form-group">
<label ref="password">Password:</label>
<input id="password" type="password" maxlength="20"/>
</div>
<button type="button" class="btn btn-primary" onclick="window.UserAPP.login()">Login</button>
<button type="button" class="btn btn-default" onclick="window.location='/signup.html'">Sign Up</button>
</form>
</div>

confirm.html

<div class="container center-block">
<form>
<div class="form-group">
<label ref="code">Code:</label>
<input id="code" type="text" maxlength="20"/>
</div>
<button type="button" class="btn btn-primary" onclick="window.UserAPP.confirm()">Confirm</button>
<button type="button" class="btn btn-default" onclick="window.UserAPP.resend()">Resend</button>
</form>
</div>

signup.html

<div class="container center-block">
<form>
<div class="form-group">
<label for="username">Username:</label>
<input id="username" type="text" maxlength="20"/>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input id="email" type="text" maxlength="120"/>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input id="password" type="password" maxlength="20"/>
</div>
<button type="button" class="btn btn-primary" onclick="window.UserAPP.signup()">Sign Up</button>
</form>
</div>

Secret.html

<h1>Secret page</h1>
<button type="button" class="btn btn-primary" onclick="window.UserAPP.logout()">Log out</button>

It could contain anything you want and a button which calls logout function.


Static web hosting on S3

S3 bucket has the feature to store and support web hosting. To host a static website, you configure an Amazon S3 bucket for website hosting and then upload your website content to the bucket. This bucket must have public read access. It is intentional that everyone in the world will have read access to this bucket. The website is then available at the AWS Region-specific website endpoint of the bucket, which is in the following format:

<bucket-name>.s3-website-<AWS-region>.amazonaws.com

API Gateway And Cognito integration:

So far, we have seen how AWS Cognito works. Now we shall integrate Cognito and API gateway.

An API gateway is the single entry point into the system. It enables users to create, publish, monitor, maintain and secure their APIs.
Features included, but are not limited to:

  • Traffic management
  • Authorization and access control
  • Monitoring
  • API version management
  • Throttling requests to prevent attacks

API Gateway is automatically scaled out and is billed as per API call.

It may look complicated for you to understand. It’s just an overview of how it interacts with Cognito with an example.

Go to API gateway select your API and click on authorizers. As shown below

Token Source is the header the token is expected in, we will use Authorization because its an RFC standard way of passing identifying information to the server. And leave token validation empty then click create.

In case if you want to test it and you need an authorizer which you could get, you should be logged in to your app. With Cognito, you need a session to get the token. Now we could use the javascript console in browser to get that token just by putting this code.

var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
userPool.getCurrentUser().getSession(function(err, session) { console.log(session.getIdToken().getJwtToken());
})

Copy that token and past in Authorizer test in API gateway console. Click on test then, you should see a successful response if you see the result of that test you may find some interesting information like username, email, etc. This token id is used to authorize users as it contains most of the information needed to authorize a user.

As it is working fine till now, go back to your API and click on Method Request hit the Authorization select the authorizer which we created and check it to save. So technically our application is now connected with the Cognito User Pool and we could use this id-token for authentication during different API calls in our application. That’s all for the basic understanding of how to connect the API gateway with Cognito.

Thanks for the read, I hope that the article was helpful.

This story is authored by Santosh Kumar. He is a Software Engineer specializing on Cloud Services and DevOps.

ZenOf.AI

AI | Machine Learning | Big Data

Engineering@ZenOfAI

Written by

ZenOf.AI

ZenOf.AI

AI | Machine Learning | Big Data

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade