Skip to content

Instantly share code, notes, and snippets.

@eddywashere
Last active April 16, 2017 01:00
Show Gist options
  • Save eddywashere/7fe49346d977f82321071910f5006568 to your computer and use it in GitHub Desktop.
Save eddywashere/7fe49346d977f82321071910f5006568 to your computer and use it in GitHub Desktop.

cognito setup for a decent user experience

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)

high level concepts

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.

@eddywashere
Copy link
Author

TODO: turn this into a github repo. This probably doesn't make as much sense without the code examples + user workflow written up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment