Amazon Cognito is an Identity Management service built to help your application handle user registration, login, and authentication without designing a complex authentication system from scratch. Cognito supports horizontal scaling, high availability, and security according to AWS Security standards.
Through Cognito User Pool, applications can authenticate users using email, phone number, password, or social login providers (Google, Facebook, Apple). Additionally, Cognito issues JWT tokens so Frontend and Backend applications can control access without storing session state on the server.
User Pool is responsible for:
App Client and Hosted UI provide integrated login interface, serving Web and Mobile applications well without building login screens from scratch.
In this workshop, you will deploy a complete authentication system based on Cognito, simulating all components commonly found in enterprise environments.
We will use two application environment groups:
This is a React application simulating the user interface (Client Application). This application will integrate Cognito’s Hosted UI and manage id_token, access_token, and refresh_token.
Frontend will be configured to:
This simulates the enterprise Service Layer. Backend includes API Gateway, Cognito Authorizer, and Lambda functions for processing logic.
APIs in this environment will:
Navigate to AWS Console → Cognito → User Pools → Create user pool
Configuration:
TravelGuideUserPool-staging
Configure password requirements:

Why these requirements?
Navigate to: App integration → App clients → Create app client
Steps:
ALLOW_USER_PASSWORD_AUTHALLOW_REFRESH_TOKEN_AUTHALLOW_USER_SRP_AUTH

Authentication Flows Explained:
Navigate to: User Pool → Users → Create user
User Information:


Note: User will need to change password on first login.
Cognito automatically handles OTP verification - no backend code needed!
Sign Up Process:
Benefits:
Cognito issues three types of tokens:
{
"sub": "user-uuid",
"email": "user@example.com",
"name": "John Doe",
"cognito:username": "johndoe"
}
Authorization: Bearer <access_token>
1. User Login
↓
2. Cognito validates credentials
↓
3. Cognito issues tokens
↓
4. Frontend stores tokens
↓
5. Frontend calls API with Access Token
↓
6. API Gateway validates token
↓
7. Lambda processes request
import { CognitoUserPool, CognitoUser, AuthenticationDetails } from 'amazon-cognito-identity-js';
const poolData = {
UserPoolId: 'us-east-1_XXXXXXXXX',
ClientId: 'your-app-client-id'
};
const userPool = new CognitoUserPool(poolData);
// Sign In
function signIn(username, password) {
const authenticationData = {
Username: username,
Password: password,
};
const authenticationDetails = new AuthenticationDetails(authenticationData);
const userData = {
Username: username,
Pool: userPool
};
const cognitoUser = new CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: (result) => {
const accessToken = result.getAccessToken().getJwtToken();
const idToken = result.getIdToken().getJwtToken();
const refreshToken = result.getRefreshToken().getToken();
// Store tokens
localStorage.setItem('accessToken', accessToken);
localStorage.setItem('idToken', idToken);
localStorage.setItem('refreshToken', refreshToken);
},
onFailure: (err) => {
console.error(err);
}
});
}
Configuration:
Authorization headerLambda receives user info:
def lambda_handler(event, context):
# User info from Cognito
claims = event['requestContext']['authorizer']['claims']
user_id = claims['sub']
email = claims['email']
username = claims['cognito:username']
return {
'statusCode': 200,
'body': json.dumps({
'message': f'Hello {username}!',
'userId': user_id
})
}