Amplify-js: Sign In with Auth.confirmSignUp

Created on 14 Jul 2020  路  14Comments  路  Source: aws-amplify/amplify-js

Is your feature request related to a problem? Please describe.
This feature is related to closed issue #2562, that request was to support signing in a user with the Auth class when a successful Auth.confirmSignUp request was made. The ticket was closed based on a UI implementation that does not solve the issue for users of the Auth class directly.

Describe the solution you'd like
The Auth library should have the option to automatically sign-in a user when they successfully complete the Auth.confirmSignUp request. This should be made possible without requiring the calling application to persist the user's credentials (username and password) between requests.

The following would be my ideal use case:

  1. A new site user is successfully registered with Auth.signUp. The site/app does NOT persist the user's password so it is no longer known by the local client.
  2. The site presents the code delivery details (e.g. SMS, Email...) to the new user so they know where to find their confirmation code.
  3. The site presents a form with a field for the username/email (pre-populated if the user has not left the flow) and an empty field for the confirmation code.
  4. The user retrieves the confirmation code from the indicated delivery method.
  5. The user enters the valid confirmation code (and username if not pre-populated) and submits the form.
  6. The site successfully performs Auth.confirmSignUp with the supplied username and code.
  7. The Auth library validates the username and code and upon receiving a valid response is able to generate a fully realized/signed-in CognitoUser locally. No further calls to Auth.signIn are required.

This flow is essentially using the confirmation code as a one-time password which seems reasonable.

Describe alternatives you've considered
Multiple alternatives are discussed in #2562 and the React UI implementation is one alternative although it appears to require persisting the user's password locally between requests which seems like a potential security risk.

Additional context
My assumption based on reading #2562 was that this would require some changes to the Cognito service. I imagine that is the case so that confirmSignUp returns a valid token but I can't find any tickets that represent that change request nor do I even know where to look for such a request.

Auth Cognito Service Team feature-request needs-discussion

Most helpful comment

Until this gets resolved, my low tech solution is to redirect the user to the sign-in page with their email address pre-populated and the following message:

You have successfully verified your account, for security purposes, please sign in to access the service.

Onboarding users is something I want to make as frictionless as possible and this is the best approach I've come up with in light of the confirmSignUp limitations. It's not great, but it's something the user experiences only once so it isn't the end of the world.

Thanks for the help! This seems like the best route as that I'm not storing the password anywhere. Autofill should also come up on web or iOS/Android.

Ultimately, the less steps the better and it would flow better if it automatically logged in. I think Amplify should improve confirmSignUp to automatically sign in the user in OR add a new method of confirmSignUpAndSignIn to automatically sign in after signing up.

All 14 comments

Hey @mousedownmike,

To clarify on the closing of the other issue, this is now implemented in all framework UI implementations of Authenticator and not just React.

Alternatively, if you would like this functionality using only the Auth category, you would just call Auth.signIn on a successful Auth.confirmSignUp. That being said, maybe the functionality could be baked into the Auth.confirmSignUp, is that what you are asking for?

Thank you for the response @jordanranz. I've updated the original post to remove mention of other UI frameworks and focus just on the use of the Auth class.

The request is to have the ability to get a signed-in user from Auth.confirmSignUp without providing the user's password. It appears that the React solution (and I presume the Angular solution) relies on having the user's password stored in the app so that it can be used to call Auth.signIn once a successful response from Auth.confirmSignUp is received.

  • The solution I propose would help in cases where the user has started a new session after registering and before confirming their account (say the confirmation email was delayed for some reason or they just changed to a different task). In that scenario, the password should no longer be stored in cache/memory so it wouldn't be available to call Auth.signIn.
  • This approach treats the username/confirmation-code as a temporary set of credentials. That's not really different from a password reset request so my preference is to take this approach over storing the user's password in the client.

I'm proposing that confirmSignUp return a promise with CognitoUser (possibly based on ConfirmSignUpOptions) giving something along the lines of:

public confirmSignUp(username: string, code: string, options?: ConfirmSignUpOptions): Promise<CognitoUser | any>

Under the covers, I would presume that if the confirmation were successful and a valid CognitoUser were returned, Auth.currentAuthenticatedUser would reflect that user.

Looking at the Cognito API documentation for ConfirmSignUp, it doesn't appear the Cognito APIs provide a trivial way to implement this so I'm guessing that this needs some support from the Cognito team.

Let me know if I can provide more information, I think it would improve the user and developer experience and possibly help keep things more secure. Thanks again!

Hey @mousedownmike,

To clarify on the closing of the other issue, this is now implemented in all framework UI implementations of Authenticator and not just React.

Alternatively, if you would like this functionality using only the Auth category, you would just call Auth.signIn on a successful Auth.confirmSignUp. That being said, maybe the functionality could be baked into the Auth.confirmSignUp, is that what you are asking for?

I'm using email verification with a link, which I believe is the most common way of user confirmation on the Internet, and the approach you suggested won't work for those cases unless the password is stored in local storage, which definitely isn't a good idea. Ideally, confirmSignUp should sign the user in automatically, it feels like a no brainer to me.

Hey @mousedownmike,
To clarify on the closing of the other issue, this is now implemented in all framework UI implementations of Authenticator and not just React.
Alternatively, if you would like this functionality using only the Auth category, you would just call Auth.signIn on a successful Auth.confirmSignUp. That being said, maybe the functionality could be baked into the Auth.confirmSignUp, is that what you are asking for?

I'm using email verification with a link, which I believe is the most common way of user confirmation on the Internet, and the approach you suggested won't work for those cases unless the password is stored in local storage, which definitely isn't a good idea. Ideally, confirmSignUp should sign the user in automatically, it feels like a no brainer to me.

One approach might be the following - on the signUp page user enters the credentials and the confirmation link is sent to our email. Meanwhile, the user is going through the confirmation process, we can try to sign in once every second on the signUp page because we have the credentials in our client memory. The first few requests will fail, with an error of non-confirmation, but after our client clicks the confirmation URL, the user will be automatically signed in, because our request will no longer fail.
The part with checking every few seconds did the user confirm the email is a bit tricky, but in this case, we don't need to save our password in any local storage.

One approach might be the following - on the signUp page user enters the credentials and the confirmation link is sent to our email. Meanwhile, the user is going through the confirmation process, we can try to sign in once every second on the signUp page because we have the credentials in our client memory. The first few requests will fail, with an error of non-confirmation, but after our client clicks the confirmation URL, the user will be automatically signed in, because our request will no longer fail.
The part with checking every few seconds did the user confirm the email is a bit tricky, but in this case, we don't need to save our password in any local storage.

I guess that approach would work in some cases, but it requires you to implement checking whether the user is now signed in repeatedly on the confirmation page. If you're simply redirecting after confirmation, then it's a race condition with the sign in requests. And what if the user closes the sign up browser tab? Or if they're on mobile, will the background tab still be able to send the requests?

It gets a lot trickier when the simpler and surefire way is to sign the user in automatically after confirming their account. If their action allowed them to confirm their account, we know for sure they're who they claim to be, so there's no reason to not sign them in.

I'm having the exact same dilemma. Has there been any resolution to this? These are the issues I'm having/possible scenarios, but I feel like there should be an easier way.

Overview:
After the user receives a Verification Code, the user enters the Verification Code, and the Account Status becomes CONFIRMED. Now that the sign up process is completed, I want to automatically sign in the user in after. It seems inefficient and redundant to redirect the user to the Sign In page to have user enter their information and sign in.

Possible Solutions:

  1. Create a confirmSignUpAndSignIn method that does what confirmSignUp does, but signs in the user after. Use the email and password from the sign up process and then dispatch the signIn action to sign in the user, but that creates a security risk as mentioned above + edge case if the user doesn't confirmSignUp right away.
  2. With the AWS Amplify Hub (Auth Listener), emit a confirmSignUp event to keep track of the user confirms the sign up process.

Possible Amplify Enhancements:

  1. Find a way combined method for both confirmSignUp and signIn, which would be something along the lines of confirmSignUpAndSignIn (If a method exists). I have looked through the AWS Docs and through the issues Amplify-js Github Repo, but have only found that others have had a similar dilemma with no apparent resolution. @mousedownmike would that be a possible solution to add a new confirmSignUpAndSignIn method?
  2. Use the AWS Amplify Hub (Auth Listener), but there aren't any events emitted when the user confirms sign up. It would make sense that confirmSignUp would emit an event, but it doesn't. (See Below)
    Additional context

I'm using the AWS Amplify Hub (Auth listener) and the only events that are emitted are the following from the docs:

    case 'signIn':
        logger.error('user signed in'); //[ERROR] My-Logger - user signed in
        break;
    case 'signUp':
        logger.error('user signed up');
        break;
    case 'signOut':
        logger.error('user signed out');
        break;
    case 'signIn_failure':
        logger.error('user sign in failed');
        break;
    case 'configured':
        logger.error('the Auth module is configured');

I'm using verification by link and as it currently stands I see no possible way to reliably (and securely) sign users in after confirming their account. This would have to be integrated into the confirmSignUp method. 馃槙

Until this gets resolved, my low tech solution is to redirect the user to the sign-in page with their email address pre-populated and the following message:

You have successfully verified your account, for security purposes, please sign in to access the service.

Onboarding users is something I want to make as frictionless as possible and this is the best approach I've come up with in light of the confirmSignUp limitations. It's not great, but it's something the user experiences only once so it isn't the end of the world.

Until this gets resolved, my low tech solution is to redirect the user to the sign-in page with their email address pre-populated and the following message:

You have successfully verified your account, for security purposes, please sign in to access the service.

Onboarding users is something I want to make as frictionless as possible and this is the best approach I've come up with in light of the confirmSignUp limitations. It's not great, but it's something the user experiences only once so it isn't the end of the world.

Thanks for the help! This seems like the best route as that I'm not storing the password anywhere. Autofill should also come up on web or iOS/Android.

Ultimately, the less steps the better and it would flow better if it automatically logged in. I think Amplify should improve confirmSignUp to automatically sign in the user in OR add a new method of confirmSignUpAndSignIn to automatically sign in after signing up.

@ashika01 and @elorzafe, is there a public roadmap for Cognito and Amplify JS? It feels like both are due for a significant revision and I'm wondering if it's time to start looking at alternatives or continue waiting for improvements.

Totally agree, on all websites when you sign up, you are already signed in, it should be already available like firebase and the rest of the world does, we use Amplify to have a almost-ready-easy-to-use platform and doing that is quite bad for us/it

+1

+1

+1

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rygo6 picture rygo6  路  3Comments

guanzo picture guanzo  路  3Comments

rayhaanq picture rayhaanq  路  3Comments

oste picture oste  路  3Comments

cgarvis picture cgarvis  路  3Comments