Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto signin after confirm email #2562

Closed
cliffordh opened this issue Jan 17, 2019 · 48 comments
Closed

Auto signin after confirm email #2562

cliffordh opened this issue Jan 17, 2019 · 48 comments
Assignees
Labels
Auth Related to Auth components/category feature-request Request a new feature

Comments

@cliffordh
Copy link

Is your feature request related to a problem? Please describe.
Currently, users must sign in after email confirmation. It would be ideal if a user did not have to sign in after creating their account and verifying their email.

Describe the solution you'd like
I would like the user to automatically be signed in after email confirmation.

Describe alternatives you've considered
I have not dug into the code to see how I might accomplish this on my own. Ideally, this should be parameterized, i.e., autoSigninAfterConfirmEmail: true.

@haverchuck haverchuck added enhancement Auth Related to Auth components/category labels Jan 17, 2019
@haverchuck haverchuck modified the milestone: Triage Jan 17, 2019
@haverchuck haverchuck added the Cognito Related to cognito issues label Jan 17, 2019
@haverchuck
Copy link
Contributor

@cliffordh - I marked this as an enhancement request. Just want to note for future consideration, however, that this flow could be awkward if user verification upon signup AND MFA are configured for a User Pool. With this scenario, an automated signin would result in the end user:

  1. Receiving a text/email after they signup.
  2. Confirming using the registration code.
  3. Immediately receiving another text/email.

Not necessarily a giant issue (assuming these messages have good subject lines configured) but definitely something to consider.

@haverchuck haverchuck removed the Cognito Related to cognito issues label Jan 17, 2019
@alpeshgaglani
Copy link

I wanted to echo same concern.. I have read several threads that have this issue. For our case, we have two customers who use phone-number-only auth (similar to WhatsApp). The first-time sign up is a critical consideration for these consumer oriented companies.
We really want to use Amplify because we love everything else about it. However, forcing the user to respond to two sms codes on first-time use is a non-starter.

Any ideas if/when this will be done?

@haverchuck haverchuck added this to the Triage milestone Jan 18, 2019
@wyzzy
Copy link

wyzzy commented Jan 22, 2019

We have a similar issue. We confirm a user sign up with an SMS and want to be able to establish a user session at that point, without an explicit sign in immediately after the sign up.

There appear to be several folks interested in this feature:

amazon-archives/amazon-cognito-identity-js#186

@Nanobrainiac
Copy link

Nanobrainiac commented Mar 4, 2019

Okay, so here we are March 4, 2019...has this feature been added yet??

This feature has been requested by users for at least a couple of years now.

@jdrydn
Copy link

jdrydn commented Mar 6, 2019

I'm with @Nanobrainiac here - three plus years have gone by and the "best solution" to this currently is:

@chetanme commented on 24 Oct 2016
From the SignUp page, you already have user's username and password in the app context. You can just use those values to create a new CognitoUser and then calling authenticateUser on the user object onSuccess of the user confirmation. On authentication success, userPool.getCurrentUser should return you the logged in user.

It's also strange how poorly documented the Amazon Cognito Identity JS package is. Plenty of examples, sure, but zero documentation.

@powerful23
Copy link
Contributor

Related #991

@hounded
Copy link

hounded commented May 14, 2019

If you have their pass from some registration form could you do something like below or is this bad?

const { email, pass } = this.form
const { code } = this.confirmation
await this.$Auth.confirmSignUp(email, code).then( async data => {
          await this.$Auth.signIn(email, pass).then( data => { 
               this.$router.push({ name: 'home' })
          })
})

@frontr-uk
Copy link

where would you get the code from?

@staneslevski
Copy link

@frontr-uk

I came across this thread because I'm trying that right now and keep failing to be able to successfully call Auth.signIn immediately after calling Auth.confirmSignUp. I'm currently not sure why, but each time I get
[ERROR] 59:30.277 AuthClass - Failed to get the signed in user No current user
as an error.

When you tried this method, did it work?

@stale
Copy link

stale bot commented Jun 17, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@sammartinez sammartinez added feature-request Request a new feature and removed enhancement labels Jun 17, 2019
@RWOverdijk
Copy link

Is this going anywhere?

@murribu
Copy link

murribu commented Sep 26, 2019

My solution was to combine the SignUp and the ConfirmSignUp Components:

export default class MySignUp extends SignUp {
  constructor(props) {
    super(props);
    this._validAuthStates = ["signUp", "confirmSignUp"];
    ...
  }

  confirm() {
    const username = this.usernameFromAuthData() || this.inputs.username;
    const { code } = this.inputs;
    if (!Auth || typeof Auth.confirmSignUp !== "function") {
      throw new Error(
        "No Auth module found, please ensure @aws-amplify/auth is imported"
      );
    }
    let self = this;
    Auth.confirmSignUp(username, code)
      .then(async () => {
        const user = await Auth.signIn(username, this.inputs.password);
        this.changeState("signedIn", user);
      })
      .catch(err => this.error(err));
  }

  showComponent(theme) {
    if (this.props.authState === "signUp") {
      return this.showSignUpComponent(theme);
    }
    if (this.props.authState === "confirmSignUp") {
      return this.showConfirmSignUpComponent(theme);
    }
  }

  showConfirmSignUpComponent(theme) {
    ...[copied from ConfirmSignUp's showComponent method]...
  }

  showSignUpComponent(theme) {
    ...[copied from SignUp's showComponent method]...
  }
}

@sarahgriffis
Copy link

Would love an update on the Cognito team! This feature seems like a no brainer.

@shbhmbnsl1
Copy link

Any update from the amplify team? I am also working on a project with a similar use case, if this feature could be added then it could be very helpful in building a customer friendly onboarding flow. We see customers getting off the application when prompted to sign in just after sign up.

@pbirsinger
Copy link

The lack of this feature is causing major friction in our signup phase and major complaints from our users

@mousedownmike
Copy link
Contributor

I've opened #6320 with a proposed use case that would resolve this without the need to persist passwords locally.

@ashika01
Copy link
Contributor

@mousedownmike Apologies for not reopening the issue. But I closed this issue with specific to UI components. I see you are talking about Auth in general. Thanks for opening the new issue. We can track it there.

@trip-sc
Copy link

trip-sc commented Sep 20, 2020

This issue pushed me over the edge to now use Firebase Auth. Just too awkward of a sign up flow in a world where frictionless sign up is very important. Especially on the first sign in and experience of our users. If it's an internal app, it isn't much of a problem. But if you have external users, it's a problem, and localstorage/inmemory on the client side of the password is not how we want to be forced to implement this.

@jjalonso
Copy link

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

@digiorgiu
Copy link

As of now, a smooth authentication workflow is only possible using a pre built UI component which exploits the Auth class and in general the Auth APIs, but it is not possibile to achieve the same result calling the authentication methods directly on the Auth class, on which the Amplify UI Components are built on.

This sounds very strange, but is a matter of fact.

@sleeviin
Copy link

sleeviin commented Mar 8, 2021

This really sucks, why they still don't fix this workflow, it's something really common and easy to implement, and looks like they don't care about it.

This makes me think to never use Cognito anymore.

@dwhiteGUK
Copy link

My solution was to store the user password in local state (it's a react app) and auto sign-in after confirmation

  async function confirmSignUp({ code }) {
    try {
      await Auth.confirmSignUp(user.username, code);

      await Auth.signIn(user.username, user.password);

      router.push('/client-protected')
    } catch (error) {
      console.log('error confirming sign up', error);
    }
  }

Works well and keeps the nice UI flow

@disbelief
Copy link

I do something very similar storing it in memory client-side, which isn't great but it works and doesn't cause users any friction.

It does seem that Cognito is barely being supported by AWS though, judging by the treatment of major long-standing issues like this and others.

@digiorgiu
Copy link

My solution was to store the user password in local state (it's a react app) and auto sign-in after confirmation

  async function confirmSignUp({ code }) {
    try {
      await Auth.confirmSignUp(user.username, code);

      await Auth.signIn(user.username, user.password);

      router.push('/client-protected')
    } catch (error) {
      console.log('error confirming sign up', error);
    }
  }

Works well and keeps the nice UI flow

It’s always a bad idea to store sensitive information on client side (easily accessible from dev tools).

@jdrydn
Copy link

jdrydn commented Mar 9, 2021

It’s always a bad idea to store sensitive information on client side (easily accessible from dev tools).

Not really applicable here, unless user in the example given points to some mad global like window.user 🤦‍♂️

@disbelief
Copy link

Agreed it's a poor security practice to store the password in memory. I ensure it's in memory for as brief an amount of time as possible. However dev tools are able to listen to network calls, so they'd see the password anyway wouldn't they?

@dwhiteGUK
Copy link

Agreed it's a poor security practice to store the password in memory. I ensure it's in memory for as brief an amount of time as possible. However dev tools are able to listen to network calls, so they'd see the password anyway wouldn't they?

That would be my thinking.... as if somebody has access to devtools on my computer then I've got bigger issues. Or is the issue that a different website can get remote access via devtools?

@disbelief
Copy link

I imagine modern browsers sandbox memory such that external websites can't access it even if they have JS on the page.

My assumption re storing sensitive data in plaintext in memory is that there could be a malicious browser extension or 3rd party/malware running on the user's machine that can access it.

Disclaimer: I'm not a security expert

@mousedownmike
Copy link
Contributor

In addition to the security concerns, storing the password in the browser doesn't resolve the issue where the confirmation step doesn't occur in the same browser (or browser session). For example, if you email the confirmation code and include a link with the code embedded, it will likely start a new browser session where you will no longer have access to the password you saved.

#6320 is still open so if you're interested in having this implemented, I would +1 that.

@dwhiteGUK
Copy link

Done. Good point, I realise my implementation was rather naive and I hadn't through if the user/customer comes back later.

@stefanvucic
Copy link

stefanvucic commented Sep 16, 2021

The problem about storing the password in local state is that user signs up and he trys to log in after 2 days, he confirms his email but there is no way to have his password at thet point to triger manually signIn method . Why you just do not make the SignIn after confirmSignUp like it is done with withAuthenticator!? Or make something like confirmSignUpWithSignIn.

@munibrahman
Copy link

You know if we just got back something like a json object back from Auth.confirmSigUp() that would have worked for us too.

The problem is that confirming a user just gives you back a SUCCESS message without any user sub info or their email etc etc. This makes it harder to try to update their information in our db.

I would also be ok with getting back information that you'd naturally get back from the Auth.currentUserInfo() endpoint, like below.

{ 
  id: undefined, 
      username: '',
      attributes: {
          "sub": "5fdf09-ceb7-4623-97fa-9c8a791a8ed9",
          "email_verified": true,
          "email": "bob@gmail.com"
      }
  }

@BernhardSmuts
Copy link

11 Mar 2022 and this is still an issue... FFS.

@mayfairr
Copy link

20 May 2022 and this is still an issue... FFS.

@kyokosdream
Copy link

kyokosdream commented May 24, 2022

Is this seriously still an issue? I can't believe this. I've setup my whole stack on AWS and am now stuck here. FFS

Why on earth is this issue closed with no resolution ?

@kyokosdream
Copy link

Background

I've thought about this for a while and I think with some work we can resolve this and improve everybody's projects. People are here because they want to create custom login, sign-up, etc components in their application but are unable to respond to user email confirmation events during the sign-up process, ruining the user experience of their application, and turning off potential clients.

I believe there are 3 options for creating a custom UI using AWS Amplify Auth:

  1. Customize the CSS of the default pre-made AWS Authenticator UI component (limited, unrealistic)
  2. Customize the components shown when the Authenticator UI component is in one of the various authState possibilities using the component in a "headless" way (more difficult and is AWS-specific) using the useAuthenticator hook.
  3. Create your own UI component that manually calls AWS Amplify Auth functions to sign-in or sign-up the user (simple, platform independent can be re-used with other authentication backends!)

Now, it's not that the built-in Authenticator UI component is terrible looking, but that it is unrealistic that developers and those building production-level software with specific design systems and their own custom animations won't need to build their own login and sign-up components. Thus, Option 1 CSS customization was out of the question, I wanted to start from scratch using a CSS framework I have recently adopted called Tailwind CSS.

I only considered Option 2 and Option 3 as viable. Despite the complexity and annoyance posed by Option 2, I decided to pursue it first. It seemed like the correct way according to AWS documentation. This is because for some reason or another, the built-in Authenticator UI component does not suffer from the issue discussed here. So I thought that this could be the ideal solution.

Option 2

Following the documentation, I wrapped my app in an <Authenticator.Provider> https://ui.docs.amplify.aws/react/components/authenticator?platform=react#useauthenticator-hook

And decided to try to conditionally show the my own custom Tailwind CSS login components according to the current authState of the Authenticator.Provider.
https://ui.docs.amplify.aws/react/components/authenticator?platform=react#access-auth-state

I honestly got sick of trying to do this, not only was I becoming frustrated with how long it was taking me to try to get the useAuthenticator to work and read all the API methods of the Authenticator when I just wanted to do a few simple actions, but I also realized that none of the best developers I know would ever write front-end UI authentication components for a specific authentication backend. They would make it re-usable and fully independent from some service like AWS, easily swapping in with Firebase or Okta if they wanted to. This is when I came to believe that Option 3 was a better architecture.

Option 3

I finally read a part of the Amplify docs that seemed designed just for my use case! It utilizes the Auth and Hub (Pub/Sub) parts of Amplify in a custom authentication flow.

The Amplify UI Component library allows you to scaffold out an end-to-end authentication flow in just a few lines of code, but you will often need to create a custom authentication flow from scratch.

Exactly. I fell back to removing the Authenticator component entirely from my application and just manually calling the Amplify Auth JS library from my own custom UI components. It just felt way simpler and more natural than trying to dig through examples and trigger transition and render custom components through the AWS Authenticator component.

Here’s the main useEffect in my App.js:

But then I come to the issue that after entering the confirmation code, user’s are re-directed to sign-in again. You can see this in the official documentation here beginning on Line 28. This means that the password would have to be stored temporarily in the client browser and also leading to the problem discussed in which they can’t confirm in another browser session or through a re-direct link in the email as has been discussed in this thread.

The Solution

Until progress can be made by AWS on improving Option 3. I think we must try to return to Option 2 and try to create our custom UI within the Authenticator component which does not suffer from this issue. I will continue to update the community as I progress.

@kyokosdream
Copy link

I've tried to find every resource on the internet related to me rendering custom UI components instead of the default ones rendered by the Authenticator.

I found this helpful article on the internet from @kylegalbraith.

The problem is that his article is now totally out of date with the newest version of the Authenticator. I've found that the hideDefault prop for the Authenticator has either been removed or does not function correctly anymore. When I tried to downgrade to legacy versions of the Authenticator used by Kyle listed here, it broke other AWS dependencies and made my app non-functional.

There is a tutorial for using withAuthenticator with custom components for an earlier version of Amplify but I was also unable to get this to work.

Still working on it.

@trip-sc
Copy link

trip-sc commented May 24, 2022

Option 4: Use firebase auth ;)

@abdallahshaban557
Copy link
Contributor

Thank you @kyokosdream for the breakdown of these possible solutions! Our team is currently exploring how to enable this feature for developers using the Amplify JS library, and we will be communicating progress on this feature on this Github issue

@github-actions
Copy link

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server amplify-help forum.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Auth Related to Auth components/category feature-request Request a new feature
Projects
None yet
Development

No branches or pull requests