This brain dump assumes a frontend js app + backend api are involved. I'll hopefully turn this into a lambda + react blog post.
To setup Cognito User Pools in a way that
- allows users to change their email address
- does not let users overwrite admin values
- fully customizable verification emails
Configure the User Pool with the following settings:
- Only administrators can create users, disable user signups
- Do not set email as a required attribute but enable it as an alias for login.
- ^ That's the only alias you'll need.
- mfa optional
- always remember user devices (why not right?)
- create two app clients: backend & frontend.
client-backend
- used in the backend api- do not generate client secret
- Enable sign-in API for server-based authentication (ADMIN_NO_SRP_AUTH)
- set attribute permissions: can write and read all attributes
client-frontend
- used on the clientside app- do not generate client secret
- set attribute permissions: read only essential attributes, only allow writes for locale (unfortunately you're not able to disable all writes completely)
You'll need to create your own signup api that uses the adminCreateUser
method to create a user and set a temp password/token that you will send the user in an email (or however you want to deliver it). To guarantee the email address is unique, you'll need to query for that user with listUsers
and check if it already exists. You'll also need to suppress the message, MessageAction: 'SUPPRESS'
, so that you can send a proper multi format email via ses or other email delivery service.
With the email, you should craft your own activation link that contains the username uuid, and "confirmation token"/tempPassword. This assumes you have a frontend app that has a route to grab that info and begin the next call to the completeSignup api. Send the username (uuid) and token (temp password) to adminInitiateAuth
which will force the NEW_PASSWORD_REQUIRED
auth challenge. Use the user submitted password when calling adminRespondToAuthChallenge
. From here your user will be able to authenticate with cognito on the clientside with their username and password. But, we're not done. In order to allow customers to request a forgot password, we'll need to also call adminUpdateUserAttributes
and set the sort of secret email_verified
attribute to 'true'
.
To allow users to change their email, you'll need to create api endpoints for updateEmail and confirmEmail. updateEmail will also have to use listUsers
to manually verify that the user email address is not in use already. Next, use adminUpdateUserAttributes
to update preferred_username
with the new email and custom:preferred_username_verification
with a secret token that you supply. Because preferred_username
is not an alias, the user won't be able to auth with it. With the confirmEmail service, you'll use the backend to get user details and compare custom:preferred_username_verification
with the supplied token. If it's a match, use adminUpdateUserAttributes
to set email
to the new email, email_verified
to 'true'
, and set both preferred_username
and custom:preferred_username_verification
to 'false'
. Or delete the attributes in another call.
With all that setup, you can integrate https://github.com/aws/amazon-cognito-identity-js for clientside session handling.
TODO: turn this into a github repo. This probably doesn't make as much sense without the code examples + user workflow written up.