User Pool#
Let's create an user pool.
AWSTemplateFormatVersion: '2010-09-09'Resources:UserPool:Type: AWS::Cognito::UserPoolDeletionPolicy: DeleteUpdateReplacePolicy: DeleteProperties:UserPoolName: !Sub ${AWS::StackName}-user-pool# Deletion protection offDeletionProtection: 'INACTIVE'# No MFAMfaConfiguration: 'OFF'# Password policyPolicies:PasswordPolicy:MinimumLength: 8RequireLowercase: trueRequireNumbers: trueRequireSymbols: trueRequireUppercase: trueUsernameAttributes:AutoVerifiedAttributes:Schema:- Name: emailAttributeDataType: StringMutable: trueRequired: true# Email providerEmailConfiguration:EmailSendingAccount: COGNITO_DEFAULTUserPoolClient:Type: AWS::Cognito::UserPoolClientProperties:ClientName: !Sub ${AWS::StackName}-user-pool-clientGenerateSecret: falseUserPoolId: !Ref UserPoolExplicitAuthFlows:- ALLOW_USER_PASSWORD_AUTH- ALLOW_USER_SRP_AUTH- ALLOW_ADMIN_USER_PASSWORD_AUTH- ALLOW_CUSTOM_AUTH- ALLOW_REFRESH_TOKEN_AUTH
Set Password#
Export variables.
export UserPoolId="us-west-2_Pj5YEMwy0"
Register a new user using cli instead of using frontend client.
aws cognito-idp admin-create-user \--user-pool-id $UserPoolId \--username hai+2@entest.io \--user-attributes Name=email,Value=hai+1@entest.io \--message-action SUPPRESS
Set password by admin instead of confirm from user email.
aws cognito-idp admin-set-user-password \--user-pool-id $UserPoolId \--username hai+1@entest.io \--password Demo@2024 \--permanent
API Gateway#
From aws apigw console, create a Cognito Authorizer. Send reequest to api gateway with token in header. We can export some variables.
export endpoint=https://9lbz0mxhk5.execute-api.us-west-2.amazonaws.com/Prod/book
Export token.
export token=eyJraWQiOiIwcmxGd1pVNCt0aGZ5WnZBVjZTUWlQSXU0bjc4eEhMV2ZKcmFxaTRuU1ZnPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI0ODcxYTNlMC0zMDUxLTcwZjctMjM5My04YWUxYTI0OTNjMjciLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAudXMtd2VzdC0yLmFtYXpvbmF3cy5jb21cL3VzLXdlc3QtMl9QajVZRU13eTAiLCJjb2duaXRvOnVzZXJuYW1lIjoiNDg3MWEzZTAtMzA1MS03MGY3LTIzOTMtOGFlMWEyNDkzYzI3Iiwib3JpZ2luX2p0aSI6IjY1MWMwNjhmLTYxZjQtNGYxYS1iMjg1LWUyODBjNGM0NDcyNCIsImF1ZCI6IjZ1dGMyMmZ1aG5zNjBtb2x0bW9vMDYxdXNmIiwiZXZlbnRfaWQiOiJiNTlmMjEzMS0xODU4LTQ5YmUtODJmZS0yZDNmMTU2OGExYmIiLCJ0b2tlbl91c2UiOiJpZCIsImF1dGhfdGltZSI6MTcxNzYzNzUyOCwiZXhwIjoxNzE3NjQxMTI4LCJpYXQiOjE3MTc2Mzc1MjgsImp0aSI6IjIzMWJmZjBlLWViYWQtNDQ1My04ZDRiLTJjYWY5NTU0NTc2OSIsImVtYWlsIjoiaGFpKzFAZW50ZXN0LmlvIn0.Ac61F59Hg9L5buz89jm7xXI2b3yEHDl0P02wPMsnKOM2_n0fWCNSblhnBLSE-lqvJuM_-nzGpYqTGNtEK-67DhrfRM-eqxqRq6Giu_f8RKtEVzBL1vaoLXDUXr5i3qY2b6FF-dpfuwnD09QT2M12V6Tml0_FEkPjwqEr44bzfZeaHGrZFCZs7_7UzNTNKW5PAu9GT9hpyonh-undmW2OgKlN7TddpqXhPKUlD5X66rzlPPgzBfTf8Bx3sW1vyjcUhvlvZmhQMRB8BAt-oVN-GtgrRD3VgtUcBCqt4JIi5RAgGR7-G2To4mwULaj76EbrVHNu4UaTsdnijeYjtVcofg
And
curl -v -H "Authorization: Bearer eyJraWQiOiIwcmxGd1pVNCt0aGZ5WnZBVjZTUWlQSXU0bjc4eEhMV2ZKcmFxaTRuU1ZnPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI0ODcxYTNlMC0zMDUxLTcwZjctMjM5My04YWUxYTI0OTNjMjciLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAudXMtd2VzdC0yLmFtYXpvbmF3cy5jb21cL3VzLXdlc3QtMl9QajVZRU13eTAiLCJjb2duaXRvOnVzZXJuYW1lIjoiNDg3MWEzZTAtMzA1MS03MGY3LTIzOTMtOGFlMWEyNDkzYzI3Iiwib3JpZ2luX2p0aSI6IjY1MWMwNjhmLTYxZjQtNGYxYS1iMjg1LWUyODBjNGM0NDcyNCIsImF1ZCI6IjZ1dGMyMmZ1aG5zNjBtb2x0bW9vMDYxdXNmIiwiZXZlbnRfaWQiOiJiNTlmMjEzMS0xODU4LTQ5YmUtODJmZS0yZDNmMTU2OGExYmIiLCJ0b2tlbl91c2UiOiJpZCIsImF1dGhfdGltZSI6MTcxNzYzNzUyOCwiZXhwIjoxNzE3NjQxMTI4LCJpYXQiOjE3MTc2Mzc1MjgsImp0aSI6IjIzMWJmZjBlLWViYWQtNDQ1My04ZDRiLTJjYWY5NTU0NTc2OSIsImVtYWlsIjoiaGFpKzFAZW50ZXN0LmlvIn0.Ac61F59Hg9L5buz89jm7xXI2b3yEHDl0P02wPMsnKOM2_n0fWCNSblhnBLSE-lqvJuM_-nzGpYqTGNtEK-67DhrfRM-eqxqRq6Giu_f8RKtEVzBL1vaoLXDUXr5i3qY2b6FF-dpfuwnD09QT2M12V6Tml0_FEkPjwqEr44bzfZeaHGrZFCZs7_7UzNTNKW5PAu9GT9hpyonh-undmW2OgKlN7TddpqXhPKUlD5X66rzlPPgzBfTf8Bx3sW1vyjcUhvlvZmhQMRB8BAt-oVN-GtgrRD3VgtUcBCqt4JIi5RAgGR7-G2To4mwULaj76EbrVHNu4UaTsdnijeYjtVcofg" https://9lbz0mxhk5.execute-api.us-west-2.amazonaws.com/Prod/book
FrontEnd#
Let's create a home page to sign in and get token.
index.html
<html><head><title>simple cognito</title><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><style>:root {box-sizing: border-box;}*,::before,::after {box-sizing: inherit;}body {background-color: antiquewhite;}.container {max-width: 800px;margin-left: auto;margin-right: auto;justify-content: center;align-items: center;display: flex;flex-direction: column;min-height: 100%;}.form {display: grid;row-gap: 10px;grid-template-columns: repeat(1, minmax(0, 1fr));gap: 15px;background-color: gainsboro;padding: 20px 20px;min-width: 350px;}.button-submit {padding: 10px 15px;border-radius: 5px;background-color: greenyellow;border: none;cursor: pointer;}.button-submit:hover {background-color: aqua;}.input-username {padding: 5px 10px;width: 100%;}</style></head><body><div class="container"><form class="form" id="form"><div><label for="username">username</label><inputtype="text"id="username"name="username"class="input-username"placeholder="htranminhhai20@gmail.com"/></div><div><label for="password">password</label><inputtype="password"id="password"name="password"class="input-username"placeholder="Demo@2024"/></div><button class="button-submit" id="submit">Sign In</button></form></div></body><script>const config = {CLIENT_ID: '1fo164cp8c6mnpbp9915gmgm3d',ENDPOINT: 'https://cognito-idp.us-west-2.amazonaws.com'}const signIn = async (username, password) => {axios.post(config.ENDPOINT,{AuthFlow: 'USER_PASSWORD_AUTH',ClientId: config.CLIENT_ID,AuthParameters: {USERNAME: username,PASSWORD: password}},{headers: {'Content-Type': 'application/x-amz-json-1.1',Accept: '*/*','X-Amz-Target': 'AWSCognitoIdentityProviderService.InitiateAuth'}}).then(response => {console.log(response)// store access token in local storagelocalStorage.setItem('AccessToken',response.data.AuthenticationResult.AccessToken)// store id token in local storagelocalStorage.setItem('IdToken',response.data.AuthenticationResult.IdToken)// open profile pagewindow.location.href = 'profile.html'}).catch(error => {console.log(error)})}document.getElementById('submit').addEventListener('click', async event => {event.preventDefault()const username = document.getElementById('username').valueconst password = document.getElementById('password').valuesignIn(username, password)})</script></html>
Let's create a profile page to decode token.
profile.html
<!DOCTYPE html><html><head><title>profile page</title><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><style>.main {max-width: 1000px;margin: auto;background-color: gainsboro;height: 100vh;}.token {width: 90%;height: 200px;margin: auto;padding: 10px;overflow: auto;background-color: beige;word-wrap: break-word;}.button-decode {background-color: orange;padding: 10px 20px;cursor: pointer;}.decoded-token {background-color: beige;}</style></head><body><div class="main"><div><h3>Access Token</h3><textarea id="AccessToken" class="token"></textarea><h3>Id Token</h3><textarea id="IdToken" class="token"></textarea><button class="button-decode" id="decode-access-token">Decode Token</button><h3>Decoded Id Token</h3><pre id="DecodedIdToken" class="decoded-token"></pre></div></div><script>// get access token from local storagedocument.getElementById('AccessToken').innerHTML =localStorage.getItem('AccessToken')// get id token from local storagedocument.getElementById('IdToken').innerHTML =localStorage.getItem('IdToken')// cognito configurationconst config = {CLIENT_ID: '1cakmv86je8vm15nu8ufbpb4la',ENDPOINT: 'https://cognito-idp.us-east-1.amazonaws.com'}// only decode not validateconst decodeToken = () => {var token = localStorage.getItem('IdToken')var base64Url = token.split('.')[1]var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')var jsonPayload = decodeURIComponent(window.atob(base64).split('').map(function (c) {return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)}).join(''))let obj = JSON.parse(jsonPayload)let dec = document.getElementById('DecodedIdToken')dec.innerHTML = JSON.stringify(obj, undefined, 2).toString()console.log(JSON.stringify(obj, undefined, 2))return JSON.parse(jsonPayload)}document.getElementById('decode-access-token').addEventListener('click', decodeToken)</script></body></html>