Cognito User Pool There Was a Problem Creating Your User Pool Please Try Again
Role 1, Serverless
AWS cognito with Python.
Introduction
The login folio is the fist thing that most web awarding users encounter. Account creation is the gateway through which all new application users pass through before they can utilise a web application. This means that authentication (account creation, login and user data management) is a disquisitional component for virtually web applications.
Cognito is designed for a diversity of application use cases. Cognito tin be used for customer side authentication of mobile devices, client side web applications (using JavaScript) and for server side hallmark (the application that is discussed in this article). The Cognito infrastructure can even provide web pages for the diverse authentication tasks.
Cognito User Pools
Cognito tin can back up 1 more more "user pools". Each "pool" contains the login and user information for a group of users. Product and test user pools can be created so that awarding testing does non bear upon the Cognito product user information.
Cognito also provides a user interface that allows management of users within a detail puddle. This user interface is available via the AWS console login, which can be protected with 2 factor authentication.
Cognito Authentication Support
The AWS Cognito service provides support for a wide range of hallmark features, For example, Cognito can support ii factor authentication for loftier security applications and OAuth, which allows an application to authenticate using an OAuth provider like Google, Facebook or Twitter.
Cognito supports the steps needed to securely create an application business relationship. This includes sending a temporary countersign to the user'south email and temporary authentication using this countersign, which allows the user to create a permanent password.
Cognito as well supports countersign reset for an existing account for the case where a user has forgotten their password. Cognito will email the user a code, which can exist used to create a new password or can also send a lawmaking to the registered mobile number. There are two ways, in which the codes can exist sent. You can utilise the default cognito messaging or can integrate with SNS/SES.
The diagram below illustrates the web folio flow for new accounts and forgotten passwords. In this demonstration application, the Spring code supports the control flow via Spring controller objects.
Lets me first walk you to the steps needed to create a user pool on AWS cognito.
- Go to the Amazon Cognito panel. You might exist prompted for your AWS credentials.
- Choose Manage your User Pools.
- In the top-correct corner of the page, choose Create a User Pool.
- Provide a name for your user pool, and choose Review Defaults to salve the name.
- On the Attributes page, cull Email address or phone number and Let email addresses.
- At the lesser of the page, choose Next Step to save the attribute.
- On the navigation bar on the left-side of the page, choose Review.
- On the bottom of the Review page, cull Create pool.
For this tutorial, I have chosen the beginning option U sername, which means that users can choose their unique usernames and sign up with them.
Annotation downward yous pool-id
Next is to create app-client-id.
- On the navigation bar on the left-side of the page, choose App clients under General settings.
- Choose Add an app client.
- Give your app a name.
- Check generate client hole-and-corner, it volition be required in our lambda functions and check server-based authentication (ADMIN_NO_SRP_AUTH).
- Choose Create app client.
- Note the App customer ID and APP Client Secret.
Now, Our AWS cognito user pool is created and we at present demand to create lambda functions to interact with it.
Lambda role: Signup
When a user needs to sign in, he/she has to decide on their primary email id and a password of atleast 8 characters long. The lambda function which will handle new user registration.
import boto3
import botocore.exceptions
import hmac
import hashlib
import base64
import json USER_POOL_ID = ''
CLIENT_ID = ''
CLIENT_SECRET = '' def get_secret_hash(username):
msg = username + CLIENT_ID
dig = hmac.new(str(CLIENT_SECRET).encode('utf-8'),
msg = str(msg).encode('utf-eight'), digestmod=hashlib.sha256).digest()
d2 = base64.b64encode(dig).decode()
render d2 def lambda_handler(consequence, context): for field in ["username", "email", "password", "proper noun"]:
if not upshot.become(field):
render {"fault": Imitation, "success": Truthful, 'bulletin': f"{field} is not nowadays", "information": None}
username = outcome['username']
email = outcome["e-mail"]
countersign = event['countersign']
proper noun = event["name"] client = boto3.client('cognito-idp') try:
resp = customer.sign_up(
ClientId=CLIENT_ID,
SecretHash=get_secret_hash(username),
Username=username,
Password=countersign,
UserAttributes=[
{
'Name': "proper name",
'Value': proper name
},
{
'Name': "electronic mail",
'Value': email
}
],
ValidationData=[
{
'Name': "email",
'Value': e-mail
},
{
'Name': "custom:username",
'Value': username
} ])except client.exceptions.UsernameExistsException as e:
except client.exceptions.InvalidPasswordException as e:
return {"error": False,
"success": True,
"message": "This username already exists",
"data": None}return {"error": False,
except client.exceptions.UserLambdaValidationException as due east:
"success": True,
"message": "Countersign should have Caps,\
Special chars, Numbers",
"data": None}
return {"error": False,
"success": True,
"bulletin": "Electronic mail already exists",
"information": None}except Exception as e:
return {"error": Simulated,
"success": Truthful,
"message": str(eastward),
"data": None}render {"error": False,
"success": True,
"message": "Please confirm your signup, \
check Email for validation lawmaking",
"information": None}
*Note: this exception (UserLambdaValidationException) volition be raised exist another pre signup lambda function which volition cheque if the same electronic mail exists in cognito or not. I volition exlain this in some other post.
Lambda : Ostend Sign upward
If a user is a new registration, She/He will be asked to verify her/his email id through a verification code sent on her/his registered email id.
import json
import boto3
import botocore.exceptions
import hmac
import hashlib
import base64
import uuid USER_POOL_ID = '<your user pool id>'
CLIENT_ID = '<your client id>'
CLIENT_SECRET ='<your customer underground>' def get_secret_hash(username):
msg = username + CLIENT_ID
dig = hmac.new(str(CLIENT_SECRET).encode('utf-8'),
msg = str(msg).encode('utf-viii'), digestmod=hashlib.sha256).digest()
d2 = base64.b64encode(dig).decode()
return d2 def lambda_handler(event, context):
client = boto3.client('cognito-idp') endeavor:
username = issue['username']
countersign = event['password']
code = event['code'] response = client.confirm_sign_up(
ClientId=CLIENT_ID,
SecretHash=get_secret_hash(username),
Username=username,
ConfirmationCode=code,
ForceAliasCreation=False, )
except client.exceptions.UserNotFoundException:
#render {"fault": True, "success": False, "message": "Username doesnt exists"}
return event except customer.exceptions.CodeMismatchException:
return {"error": True, "success": False, "bulletin": "Invalid Verification code"}except customer.exceptions.NotAuthorizedException:
return {"error": Truthful, "success": False, "message": "User is already confirmed"}except Exception as e:
return {"error": True, "success": False, "bulletin": f"Unknown error {due east.__str__()} "}return event
Lambda : Resend Verification code
The verification is valid simply for 24 hours, Lets say the user missed that window to confirm her/his registration, and then he can request the verification code again from cognito.
import json
import boto3
import botocore.exceptions
import hmac
import hashlib
import base64
import uuid USER_POOL_ID = '<your user puddle id>'
CLIENT_ID = '<your customer id>'
CLIENT_SECRET ='<your customer secret>' def get_secret_hash(username):
msg = username + CLIENT_ID
dig = hmac.new(str(CLIENT_SECRET).encode('utf-8'),
msg = str(msg).encode('utf-8'),
digestmod=hashlib.sha256).digest()
d2 = base64.b64encode(dig).decode()
return d2 def lambda_handler(event, context):
customer = boto3.client('cognito-idp') endeavor:
username = event['username'] response = client.resend_confirmation_code(
ClientId=CLIENT_ID,
SecretHash=get_secret_hash(username),
Username=username,
)
except client.exceptions.UserNotFoundException:
return {"error": True, "success": False, "message": "Username doesnt exists"}except client.exceptions.InvalidParameterException:
return {"error": Truthful, "success": Simulated, "message": "User is already confirmed"}except Exception every bit e:
render {"fault": True, "success": False, "bulletin": f"Unknown error {e.__str__()} "}return {"fault": False, "success": Truthful}
Lambda: Forgot Countersign
Lambda function to send an electronic mail to the user , in example he forgets her/his password. Invocation of this lambda function will transport a verification lawmaking to the e-mail/phonenumber.
import json
import boto3
import botocore.exceptions
import hmac
import hashlib
import base64
import uuid USER_POOL_ID = '<your user pool id>'
CLIENT_ID = '<your customer id>'
CLIENT_SECRET ='<your client undercover>'
def get_secret_hash(username):
msg = username + CLIENT_ID
dig = hmac.new(
str(CLIENT_SECRET).encode('utf-8'),
msg = str(msg).encode('utf-8'),
digestmod=hashlib.sha256).digest()
d2 = base64.b64encode(dig).decode()
render d2 def lambda_handler(event, context):
customer = boto3.client('cognito-idp') try:
username = upshot['username'] response = client.forgot_password(
ClientId=CLIENT_ID,
SecretHash=get_secret_hash(username),
Username=username,)
except client.exceptions.UserNotFoundException:
return {"error": Truthful,
"data": None,
"success": False,
"message": "Username doesnt exists"}except client.exceptions.InvalidParameterException:
return {"fault": True,
"success": Faux,
"data": None,
"message": f"User <{username}> is non confirmed yet"}except client.exceptions.CodeMismatchException:
render {"error": True,
"success": False,
"information": None,
"message": "Invalid Verification code"}except client.exceptions.NotAuthorizedException:
return {"mistake": True,
"success": False,
"data": None,
"message": "User is already confirmed"}except Exception as eastward:
return {"fault": True,
"success": Fake,
"information": None,
"message": f"Uknown error {e.__str__()} "}render {
"fault": False,
"success": Truthful,
"message": f"Please check your Registered email id for validation code",
"data": None}
Lambda: Confirm forgot password
After the user receives a code on her/his email or telephone number, a dissimilar lambda functions needs invocation, to check authenticity of the validation code. If the verification code is correct, User password will be replaced with the new password.
import json
import boto3
import botocore.exceptions
import hmac
import hashlib
import base64
import uuid USER_POOL_ID = '<your user pool id>'
CLIENT_ID = '<your customer id>'
CLIENT_SECRET ='<your client secret>' def get_secret_hash(username):
msg = username + CLIENT_ID
dig = hmac.new(str(CLIENT_SECRET).encode('utf-8'),
msg = str(msg).encode('utf-8'), digestmod=hashlib.sha256).assimilate()
d2 = base64.b64encode(dig).decode()
render d2 def lambda_handler(upshot, context):
client = boto3.client('cognito-idp') endeavor:
username = result['username']
password = outcome['password']
code = event['code'] client.confirm_forgot_password(
ClientId=CLIENT_ID,
SecretHash=get_secret_hash(username),
Username=username,
ConfirmationCode=lawmaking,
Password=password,
)
except customer.exceptions.UserNotFoundException as e:
return {"error": True,
"success": False,
"information": None,
"message": "Username doesnt exists"}
except customer.exceptions.CodeMismatchException equally eastward:
return {"mistake": Truthful,
"success": False,
"data": None,
"message": "Invalid Verification code"}except client.exceptions.NotAuthorizedException every bit e:
return {"error": Truthful,
"success": False,
"data": None,
"bulletin": "User is already confirmed"}except Exception as due east:
return {"error": True,
"success": False,
"data": None,
"message": f"Unknown fault {east.__str__()} "}return {"error": Imitation,
"success": True,
"bulletin": f"Password has been changed successfully",
"information": None}
You can check which all users are currently signed up with your app, and which all users are in confirmed or unconfirmed state on cognito panel.
The last bit is to provide login for the users who have successfully completed their registration process.
import boto3
import botocore.exceptions
import hmac
import hashlib
import base64
import json USER_POOL_ID = ''
CLIENT_ID = ''
CLIENT_SECRET = '' def get_secret_hash(username):
msg = username + CLIENT_ID
dig = hmac.new(str(CLIENT_SECRET).encode('utf-eight'),
msg = str(msg).encode('utf-8'), digestmod=hashlib.sha256).assimilate()
d2 = base64.b64encode(dig).decode()
return d2 def initiate_auth(client, username, password):
secret_hash = get_secret_hash(username)
try:
resp = client.admin_initiate_auth(
UserPoolId=USER_POOL_ID,
ClientId=CLIENT_ID,
AuthFlow='ADMIN_NO_SRP_AUTH',
AuthParameters={
'USERNAME': username,
'SECRET_HASH': secret_hash,
'Countersign': password,
},
ClientMetadata={
'username': username,
'countersign': password, }) except client.exceptions.NotAuthorizedException:
return None, "The username or password is incorrect"
except client.exceptions.UserNotConfirmedException:
return None, "User is not confirmed"
except Exception as due east:
return None, east.__str__()
render resp, None def lambda_handler(result, context):
customer = boto3.client('cognito-idp')
for field in ["username", "password"]:
if event.get(field) is None:
return {"error": True,
"success": Simulated,
"message": f"{field} is required",
"information": None}
resp, msg = initiate_auth(client, username, password)
if msg != None:
render {'message': msg,
"error": True, "success": False, "data": None} if resp.get("AuthenticationResult"):
render {'message': "success",
"mistake": False,
"success": Truthful,
"data": {
"id_token": resp["AuthenticationResult"]["IdToken"],
"refresh_token": resp["AuthenticationResult"]["RefreshToken"],
"access_token": resp["AuthenticationResult"]["AccessToken"],
"expires_in": resp["AuthenticationResult"]["ExpiresIn"]
"token_type": resp["AuthenticationResult"]["TokenType"]
}}
else: #this lawmaking block is relevant but when MFA is enabled
render {"error": True,
"success": False,
"information": None, "bulletin": None}
In the side by side part, we will explore linking these lambda functions with API Gateway to access signup functionalities and also the employ of access token to secure our other application API's. Cheers!
My Eth Address: 0x01445B7d9D63381D0e7A6d8556F62A24197BeA1F
My Bitcoin Accost: bc1qhdzydl7kwjk8reznvj3yd6s0cg7e7r2sasgfxc
Source: https://medium.com/@houzier.saurav/aws-cognito-with-python-6a2867dd02c6
0 Response to "Cognito User Pool There Was a Problem Creating Your User Pool Please Try Again"
Post a Comment