Implementing OTP based Phone auth in Amazon Cognito using Custom Auth Flow & Amplify
prashanthhn.png Prashanth HN
6 min read Dec 18, 2019
aws

Implementing OTP based Phone auth in Amazon Cognito using Custom Auth Flow & Amplify

aws

Few more things we need to take care of

Above implementation only talks about signIn and not new sign ups. Unlike signIn method, signUp requires a password to be sent. I ended up generating a strong password on the client side and passing it to signUp. This is fine since the user will never need the password to login.

Auth.signUp({
  username: "+91" + this.state.username,
  password, //generated password
})

I have configured Cognito to verify phone number on signup, so first time users will receive their 6 digit code from Cognito itself. We will need to call Auth.confirmSignUp() instead of Auth.sendCustomChallengeAnswer() in this case.

verifyCode = () => {
  const username = "+91" + this.state.username
  Auth.confirmSignUp(username, this.state.code, {
    forceAliasCreation: true,
  })
}

Another hicup here is that Cognito won’t automatically signIn the user after confirmation! Now, if we call signIn() without password, it will trigger another SMS/Text with a code, which will annoy the user. To avoid this we need to call signIn() with password. So, we need to keep the password we generated in signup process in the client to reuse here.

One final gotcha

When first time user registers and doesn’t complete the confirmation step, Cognito sets the user status as “confirmation pending”. Calling the Auth.signUp() next time will fail with error “user already exists”. Calling Auth.signIn() will result in “confirmation pending” error. We can’t call Auth.signIn() with password since we don’t have the password. This puts the account in a limbo! This will not be an edge case since lot of times people enter random numbers when asked for a phone number & they never get the OTP/code since they don’t own that phone number. This random number could potentially be a real phone number of someone else.

To address this issue I came up with a Lambda function which will be called before signup() to check if the account is in this limbo. If it is, I delete the account and tell the client to go with normal user registration process.

This post was cross posted from hnp.dev

FAQs

1. Why use AWS Amplify with Cognito Custom Auth?

Amplify provides streamlined integration with Cognito, allowing developers to manage authentication state, user sessions, and UI updates easily, even in complex flows. While it abstracts much of the boilerplate, it still gives enough control to hook into custom authentication logic and work with Cognito triggers and Lambda functions.

2. What are best practices for securing OTP logic in a custom auth flow?

Avoid storing OTPs in plaintext. Use short-lived storage with TTLs (like DynamoDB with expiration fields), encrypt OTPs if needed, and enforce retry limits to mitigate brute force. Also, ensure rate-limiting at the API layer to prevent SMS spamming.

Application Modernization Icon

Innovate faster, and go farther with serverless-native application development. Explore limitless possibilities with AntStack's serverless solutions. Empowering your business to achieve your most audacious goals.

Talk to us

Author(s)

Tags

Your Digital Journey deserves a great story.

Build one with us.

Recommended Blogs

Cookies Icon

These cookies are used to collect information about how you interact with this website and allow us to remember you. We use this information to improve and customize your browsing experience, as well as for analytics.

If you decline, your information won’t be tracked when you visit this website. A single cookie will be used in your browser to remember your preference.