Why We Need AWS Cognito Authentication

Jim Wu
6 min readDec 20, 2019

Whether you have suffered from how your service to authenticate and authorize users. If we don’t want to host a server to design the authenticate and authorize mechanism. AWS Cognito might be a better alternative for your design considerations.

There are two main components User Pool and Identity Pool from AWS documentation.

https://docs.aws.amazon.com/en_us/cognito/latest/developerguide/what-is-amazon-cognito.html
https://docs.aws.amazon.com/en_us/cognito/latest/developerguide/what-is-amazon-cognito.html

User Pool

user directories that provide sign-up and sign-in options for your web and mobile app users. Once user has been authenticated with User Pool, user can get auth token from Amazon Cognito. And then user can utilize this token to access retrieve AWS credentials

https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-identity-federation.html

Identity Pool

The main purpose is to obtain a temporary AWS credentials to access AWS services. Firstly, we need to get JWT obtained from User Pool to exchange credentials with Identity Pool. After that, we can use this credentials to authorized services.

Today, we’d like to share you how we leverage AWS User Pool to help completed authentication.

Let’s Get Started with User Pool

First of all, I’d like to introduce how to authenticate the user via AWS Cognito. Here, let me show you Facebook login as example.

Step 1

Login into AWS Cognito panel via https://console.aws.amazon.com/cognito and you need to create an user pool by clicking “create a user pool” button as follows.

User Pool Panel

Next, input name for your first user pool and basically you can create the user pool by clicking “Review defaults”.

Create User Pool with Default Review

Step 2

Now, you have created an user pool and the following you will need to configure with app integration. Tap the “App Integration” and add Amazon Cognito Domain and then save the changes.

Adding Amazon Cognito Domain

Step 3

After that, we need to add app client from UI Customization item. By clicking “Add app client”, we also require to input app information and please make sure “Generate client secret” must be checked. That is a required parameter for the following steps of authenticate users and getting tokens etc.

Create App Client

Step 4

By adding identify provider under Federation, you need to create one of providers to serve authenticate your users. For illustration, we take Facebook as example to integrated with our app clients. Due to out of discussion for how to create Facebook app, we don’t share related steps and configuration here. After you enable Facebook in Identity Provider and then go back to App clients settings.

Enable Facebook as Identity Provider

Step 5

In App client settings, you must have checked Facebook in “Enabled Identity Providers”. Also, please offer your Callback URLs at least in Sign in and Sing out. That means if user sign in or sign out successfully, the callback URL will be fired from AWS Cognito.

Configure Your Callback URLs

If you don’t have your hosted server yet, you might need to create your own server in your local machine. For example, you run a python server listening port 4200. At the end, you have finished the whole settings of user pool with Facebook.

How to Authenticate Users

With Cognito login URL, we will use it to authenticate users. The following information you can find in your AWS Cognito panel

{domain}: Your customized domain in step 2

{region}: The region the AWS Cognito Domain

{client_id}: Created app client id

redirect_uri: Put callback URL here

scope: Your preference for auth scope

The detailed of scope parameter in which you want to authenticate. You can refer to AWS Cognito login endpoint. The login will be look like this.

https://{domain}.{region}.amazoncognito.com/login?response_type=code&client_id={client id}&redirect_uri=http://localhost:4200&state=STATE&scope=openid+profile+aws.cognito.signin.user.admin 

Copy this URL and paste to browser for testing. Since we have selected both Facebook and Cognito User Pool, users will see the two options for their login.

After login successfully, authorization code will be brought as parameter from Callback URL.

Login Callback with Authorization Code

Cognito AWS JWT

There is a detailed Cognito auth document of how to obtain ID, Access and Refresh JWT. When your hosted server receives the callback with authorization code, then you are able to get JWT by the following URL and payload to perform HTTP POST request.

https://adrawgill-fblogin.auth.us-east-1.amazoncognito.com/oauth2/token

In HTTP Header, there two attributes must be set. We must base64 encode with string {your client id}:{your client secret}

Content-Type: application/x-www-form-urlencoded
Authorization: Base64Encode(client_id:client_secret)

In request body, you must fill the value for grant_type, authorization_code, client_id and redirect_uri.

grant_type={authorization_code}&client_id={client_id}&redirect_uri=http://localhost:4200

At the end, after firing HTTP POST request, you will get JWT from HTTP response as follows.

How to Authenticate ID Token

In the last, I’d like to share how you authenticate user via Amazon Cognito JWT. There are three JWTs as we mentioned earlier. We can easily to verify token by the following node snipped code.

const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');
const USER_POOL_ID = "user_pool_id"; //place your user pool id here
const CLIENT_ID = "client_id"; // place your client id here
const REGION = "region"; //place your cognito region here
const ISSUER_URI = "https://cognito-idp." + REGION + ".amazonaws.com/" + USER_POOL_ID;
const JWKS_URI = ISSUER_URI + "/.well-known/jwks.json";
let client = jwksClient({
jwksUri: JWKS_URI,
});

run();

function getKey(header, callback) {
client.getSigningKey(header.kid, (err, key) => {
var signingKey = key.publicKey || key.rsaPublicKey;
callback(null, signingKey);
});
}

function run() {
let idToken="your id token" // place your id token

jwt.verify(idToken, getKey, { audience: CLIENT_ID, issuer: ISSUER_URI }, function(err, decoded) {
console.log("JSON:", JSON.stringify(decoded));
});
};

Below is result from executing program.

{ 
"at_hash":"XXXXXXXX_Wh-83O2w_XXXX",
"sub":"xxxxx2ea-294b-4f0c-b24e-4b1e1a0xxxxx",
"cognito:groups":[
"us-east-1_USER_POOL_ID_Facebook"
],
"iss":"https://cognito-idp.us-east-1.amazonaws.com/us-east-1_USER_POOL_ID",
"cognito:username":"Facebook_10215021234567890",
"nonce":"xxxxxxxxxxxxxx-Yel3ZjU2hrTL9WoiQc1z_xxxxxGFt0wtrbJR02PzSd1M6Leg7gyChmXtxaqstKB9wRfaBPiiMvLY7-pp5NQBn_7dcclTp3HI_xxxxxzqMdozUQk0G2iRa_0sR31c4T-xxxxxxxxxxxx",
"aud":"xxxxxb0gs77ogcsqb4m9sxxxxx",
"identities":[
{
"userId":"10215021234567890",
"providerName":"Facebook",
"providerType":"Facebook",
"issuer":null,
"primary":"true",
"dateCreated":"1573551475915"
}
],
"token_use":"id",
"auth_time":1576828929,
"exp":1576832529,
"iat":1576828929,
"email":"youremail@email.com"
}

Summary

Congratulations! You have completed how to leverage AWS Cognito User Pool and authenticate your users. It’s pretty simple and convenient, right !

Will sharing the Identity Pool soon.

References

--

--