In Cognito I have created the user name with an unique id for example (dbdhdydhdhhdh) and I am putting my email address to get the temp password to log in my UI ?
But when I receive an email it's shows my unique id instead of name. So I trigger the lambda function to get my name in the email .My lambda is working fine and it's shows my user name when I get the password but along with the username the unique id is also reflecting.
Any suggestion how can I hide that unique id please ?
Aws Cognito has lambda triggers may be you can customize your email content in that lambda trigger.
Please find the link [https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html]
Your question is not very clear, If I understood it correctly you want to send a custom email with other attributes (given_name, family_name etc), it is possible with Lambda triggers.
Have a look at this link - https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-custom-message.html
Your user attributes should be coming inside
event.request.userAttributes
and you should be able to use them in your email message.
Related
I need to validate user's email before allowing them to proceed with account creation.
What will be the best way of doing so in Django ?
I was thinking of sending cookies with UUID which will be used during registration.
email_validation_DB:
UUID | Email | Confirmation Code | is_verified
Then, when user will click on register. UUID will be used to get the verified email address from email_validation_DB and proceed with account creation.
Instead of allowing users with only verified emails to proceed, I would suggest that you allow any user to register but activate their account only after they verify their emails.
What you can do is create a hash token and send the email with hash token and a link. When user clicks on the link, you can verify the token and activate the account. Here is a good tutorial about this - https://www.javatpoint.com/django-user-registration-with-email-confirmation
Alternatively, you can use a python package. Here is a good one - https://github.com/LeoneBacciu/django-email-verification. You can also use this package to add additional functionalities around email sending like forgot password etc.
In my user pool, I currently see two options for the login flow:
Using username and email adress
Using email adress or phone number
Option 1: The username is unique. You will get an error message if you try to register again with this username. BUT: The email address is not unique. You can try to register again with this email address. The user will then be created in the User Pool, but you will not be able to reconfirm this email address.
Option 2: The email address and / or phone number are unique. But the username can no longer be used to log in.
What do I want?
I need a mix of both options. I want my users to log in with username AND email address (which is the case with option 1), but I don't want to allow them to create multiple accounts with the same email address (they need a unique email as with option 2).
Is there an easy way to accomplish this? I couldn't find anything in the Cognito Console and feel like I need something like a custom Lambda trigger .... Thanks for any tips!
Your are already going into the right direction. You need a pre-signup lambda to do the check of email uniqueness for you. Should be relatively straightforward Here is the link to the documentation about how to set up such lambda:
https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-sign-up.html
Your Lambda needs to be able to execute actions on the User Pool to figure out if user with a specific email already exists.
The easiest way to search for such users is to use the ListUsers API (https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ListUsers.html) with a filter to select only users having the email address in question.
We have implemented the Custom Auth Triggers as described here. We have the user pool set up to let users login with either phone number or email.
The problem I am having is determining what medium (email or phonenumber) the user signed in as. I am using CognitoIdentityServiceProvider#signUp to reg / login a user.
When observing the event passed into the define / create / verify auth triggers, it seems like doesn't pass through what the username was used to initiate the authentication flow.. only the user attributes which in my case there could be both email or phone. I need to know which one it is so I know if i need to send the code through SMS or Email.
I have tried to add a custom UserAttribute with a prefix of custom: so I could do something like custom:preferredAuthMedium but that doesn't seem to populate the UserAttributes map on the user even though the docs say it should.
Is there a standard way to do this with the custom authentation flow?
This is a workaround by adding a custom attribute during passwordless login
Actually, the authenticationUser function needs to identify whether the user is adding email or phone during login
Step 1: during login process, before calling initiateAuthCommand, First set a custom attribute in Cognito user object - logged_in_by - email or phone
Step 2: once you add a key after that InitiateAuthCommand will be started and call the triggers
Step 3: When createAuthChallenge runs at the time we will have userAttributes.logged_in_by
If this attribute contains email this indicates that the user is trying to login with the email and we need to send OTP over email.
If this attribute contains a phone this indicates that the user is trying to log in with the phone and we need to send OTP over the phone number.
Different medium requires their own confirmation.
The following attributes says which medium the user signed up or verified for,
phone_number_verified is phone number.
email_verified is for email.
Hope it helps.
Cognito has a migration lambda that allows us to confirm a user in our db. They send the email and PW to Cognito, the lambda fires, we verify matches, and the user is entered into Cognito.
At this point - behind the scenes - Cognito generates a username of some kind (UUID). The problem is, I need a way to get this username into our existing database, because our systems going forward will no longer rely on email and instead rely on this username.
Ideal flow:
Sign In
Migration Succeeds
Cognito generates username
Username is sent to our server.
Now because we have email set to auto-verified, no post-confirmation lambda can be called. The only way I see to do this with Cognito as-is is to either:
Ask users who already exist in our system to confirm their email again. This is a non-starter
Create a post-auth lambda, check user login count through a custom attribute, and if 0 (or if not already registered with the service, etc.) migrate the username to the new service.
If there is any other way to do this, please let me know.
After the user migration lambda is called your pre sign-up lambda will be called, assuming you have implemented it. The parameters received by your lambda will include username with the value being the UID you referenced. Parameters will also include user attributes containing email. You can use this information to update your database.
I did not want to add the PreSignup trigger, its a complicated way of doing it if you already rely on PostConfirmation, and if the majority of new users won't be migrations. My use case has a frontend initiate the signup process as well, which I use here.
Instead, I set a Cognito attribute on the new user during the UserMigration trigger. It could be 'user_migration': <oldUserSub>, or however you want to mark it. Just make sure you allow this property within the Cognito user pool settings.
When the UserMigration trigger returns, this information is now accessible through verifying the IdToken, or found in the JWT on the frontend if you're using that. So, when the user is migrated into Cognito and the response gets back to the Cognito client on the frontend, I can now recognize this user needs to be migrated into my personal database. Seeing this, I'll call a new endpoint on my backend to handle this. This new endpoint does exactly what PostConfirmation would typically do.
Then just delete the 'user_migration' property from the Cognito user, return the new user data to the frontend and everything should be set up.
You can use Pre sign-up trigger. In order to detect if the trigger event came from your migration trigger, you can check at the trigger_source value from the event object. In my case (i'm using migration trigger) the value is PreSignUp_AdminCreateUser. By knowing the value of trigger_source you can differentiate if it was migrated or regular user. You can also check the user attributes to know whether the email or phone is verified or not.
Here's my sample code on python:
def lambda_handler(event, context):
trigger_source = event.get('triggerSource')
user_attributes = request.get('userAttributes')
email_verified = user_attributes.get('email_verified')
if trigger_source == 'PreSignUp_AdminCreateUser' and email_verified == 'true':
# create user on db
Using the AWS's Cognito one can gain a lot since most of the functionalities (if not all) are already implemented by AWS. But I've faced a situation which I'm not sure how to implement using Cognito. Consider the following two scenarios:
Sign up:
User signs up by providing an email, and a password
An email is sent to the user with a confirmation code
User sends the username and confirmation code to complete the process
Forgot password:
User requests a code by sending his / her username
An email is sent to the user with the generated code in the previous step
User resets the password by providing the username, the new password, and the code
The statements above are tailored according to how AWS Cognito is implemented. And as you can see, the two final steps require different input in each of the scenarios. Now, my question is why AWS Cognito uses the same email template (in the second step) for both of them?
AFAIK, there's only one template in Cognito ("Message customizations" section) and it is used regardless of the email is sent to confirm user's email ownership or user has requested for a password reset code.
This is a problem for me since I want the content of the two emails to be different. For starters, they should contain different links in them.
Is there a way to send two different emails for confirmation code and forgot password in Cognito?
As it turned out the answer is to use Custom message from Triggers. Cognito lets you specify lambda functions for the different event generated in a user pool. One of which is Custom message. This lambda function is called each time an email is about to be sent to the client. Using the input data given to the lambda function, one can realize which scenario it is and compose the correct content for that email.
Here's the link to the documentation:
https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-custom-message.html