How to Set Cognito preferred_username for User When email, phone, and preferred_username Can All Be Used as Aliases?

0

I am using Cognito User Pools for a ReactJS SPA via amazon-cognito-identity-js (https://www.npmjs.com/package/amazon-cognito-identity-js).

Intention: I would like to give all users in a user pool the flexibility to log in through aliases for (1) Email, (2) Phone, and (3) Preferred Username. Ideally, they would have the choice to use all three--granted that their email address and phone number are verified.

I have gone in circles looking at various AWS docs. I searched for code examples of how someone would do this. Handling the preferred_username is the most concerning aspect, when email address and phone number can also be used as aliases too. I am not sure of the approach I have derived, so I wanted to see if someone could weigh in.

I have been referencing the following:

I wanted to capture all user data during the Registration of a user account, using the signUp method in amazon-cognito-identity-js.

signUp(username: string, password: string, userAttributes: CognitoUserAttribute[], validationData: CognitoUserAttribute[], callback: NodeCallback<Error, ISignUpResult>, clientMetadata?: ClientMetadata): void

However, according to the AWS Cognito User Pool Attributes link above....

If you select preferred_username as an alias, your user can provide the value only when they confirm an account. They can't provide the value during registration. ``

Separately, if you select preferred_username, verified email address, and verified phone number options for aliases....and send the user's email address as the first parameter to signUp, it results in an HTTP 400: InvalidParameterException: Username cannot be of email format, since user pool is configured for email alias.

So, the signUp method is expecting a username value (not email) when email address is selected as an alias. The same is true for phone number if phone number is selected as an alias. This makes sense, as both attributes are being used as aliases and must be verified, so both should have unique values (vs two email addresses or two phone numbers).

When email is not selected as an alias and the email address value is sent as the username (first) parameter to the signUp method call, Cognito assigns a UUID (format: {d}8-{d}4-{d}4-{d}4-{d}12) for the username. The AWS docs (first link above, Option 2, under Using aliases to simplify user sign-up and sign-in) specifically state that when an email address is supplied as the username param, the email attribute is populated with this value....and a similar process is true for the phone_number attribute. I have checked and a user can log in using this auto-generated UUID as the username value.

So, when all three aliases are allowed and the signUp method is used:

  • I cannot supply the preferred_username value in the attributes list (3rd parameter) during the registration.
  • I cannot use an email address or phone number as the username value (due to the 400 above--it is similar for phone, just sub "email" in the error with "phone number")
  • I can set the user's email address and phone number values using the attribute list.
  • I can specify a preferred username as the first parameter as long as it is not in the format of an email or a phone number.
  • Once the user confirms their account by using the confirmation code sent in an email to verify their email address, I can then set the preferred_username value via an attributes list supplied to the CognitorUser.updateAttributes method.

Possible Approach: I can have a process of gathering all user info minus preferred username --> register via signUp invocation --> prompt the user to enter the confirmation code they are sent via email --> with the account now being confirmed, prompt the user to enter their preferred username --> save the preferred_username value using the CognitorUser.updateAttributes method. During the registration by using the signUp method, I must supply a username as the first parameter. I could prompt the user earlier in the process to provide their preferred username and include that as the username parameter as well as save it post-confirmation as the preferred_username. Later, if they want to change their username, the preferred_username could be updated with the new value, while the original username value stays unchanged. This would mean a disparity between those values at this point, and an account can be logged into via two different usernames (the username and the preferred_username). But does it matter? Or should I use CryptoJS and generate a "random" UUID for the username value when registering via signUp? As mentioned above, the UUID can be used to log in as well.

Is this a good approach? Or am I missing something or adding unneeded complexity?

asked 2 years ago126 views
No Answers

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions