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

Support for email-only SignUp through withAuthenticator #104

Closed
rlmartin opened this issue Dec 27, 2017 · 47 comments
Closed

Support for email-only SignUp through withAuthenticator #104

rlmartin opened this issue Dec 27, 2017 · 47 comments
Assignees
Labels
Auth Related to Auth components/category feature-request Request a new feature
Projects

Comments

@rlmartin
Copy link
Contributor

I'd like to be able to expose a SignUp form (and corresponding ConfirmSignUp) that shows only email address, not username. Unfortunately the Mobile Hub project creation doesn't fully support this (it creates a user pool with a type that still requires a username), but we could SHA-2 hash the email address in place of the username and then rely on the "alternative sign in" support for email address in the SignIn form.

The same support goes for phone number in place of email address.

The withAuthenticator HOC could take a props argument with a usernameTypes property that would be an array of enums (values: email, phoneNumber, username); this could then be used by all applicable auth components (SignUp, ConfirmSignUp, SignIn, ForgotPassword) for both display and data processing.

I'm immediately focused on the aws-amplify-react-native project and could take a pass at implementing it - but support in aws-amplify-react project would be necessary too.

@mlabieniec mlabieniec added the feature-request Request a new feature label Dec 27, 2017
@mlabieniec mlabieniec added this to Icebox in aws-amplify via automation Dec 27, 2017
@mlabieniec
Copy link
Contributor

mlabieniec commented Dec 27, 2017

@rlmartin thanks for the feedback. We are working on signup with custom attributes, it's in review and pending a few changes in PR #79 . Will look at your feedback for some enhancements to that as well.

@mlabieniec mlabieniec added enhancement and removed feature-request Request a new feature labels Dec 27, 2017
@rlmartin
Copy link
Contributor Author

@mlabieniec thanks for pointing out that other PR. I had seen it, but it didn't eliminate the requirement of username in the SignUp component so I created this issue. However I can see where you'd like to get that PR merged first, then consider this enhancement. Tell me if I can lend a hand.

@mlabieniec mlabieniec moved this from Icebox to Backlog in aws-amplify Jan 9, 2018
@mlabieniec mlabieniec moved this from Backlog to Icebox in aws-amplify Jan 21, 2018
@mlabieniec
Copy link
Contributor

@rlmartin Just fyi, we are working on abstracting out the authentication and higher level logic into the aws-amplify core package. This way, react and react-native can share all basic functionality i.e. persistent auth, federation, session management etc. So you would basically work with react-native the same way as aws-amplify-react. We are shooting to finish it this sprint, but it may end up in the following release at this point. Once that's out would like to get your feedback and contributions on that (in aws-amplify core).

@rlmartin
Copy link
Contributor Author

👍

@dillonbailey
Copy link

@rlmartin is there presently a way to use amplify and allow signup with email as username?

@ldgarcia
Copy link
Contributor

ldgarcia commented Feb 19, 2018

@dillonbailey yes, but you need to write your own custom SignUp component.

Modify the signUp function to use something like this:

// const attributes = { ... }
Auth.signUp({
  username: email,
  password: password,
  attributes
})
  .then(data => {
  this.changeState('confirmSignUp', email)
})
  .catch(err => {
  this.error(err)
})

@rlmartin
Copy link
Contributor Author

rlmartin commented Feb 19, 2018

@dillonbailey I actually took a different approach. Whenever I set email, I set username to a hash of the email. Unfortunately the change is in a private repo so I can't give you a link to the commit, but it looks roughly like this:

Overridden SignUp.js:

import React from 'react';
import { I18n } from 'aws-amplify';
import { Email, ErrorRow, Header, LinkCell, Password, SignUp as CoreSignUp } from 'aws-amplify-react-native';
import { Button, View } from 'react-native';
import sha from 'sha.js';

const Footer = (props) => {
  const { theme, onStateChange } = props;
  return (
    <View style={theme.sectionFooter}>
      <LinkCell theme={theme} onPress={() => onStateChange('confirmSignUp')}>
        {I18n.get('Confirm a Code')}
      </LinkCell>
      <LinkCell theme={theme} onPress={() => onStateChange('signIn')}>
        {I18n.get('Sign In')}
      </LinkCell>
    </View>
  )
}

export default class SignUp extends CoreSignUp {
  showComponent(theme) {
    return (
      <View style={theme.section}>
        <Header theme={theme}>{I18n.get('Sign Up')}</Header>
        <View style={theme.sectionBody}>
          <Email
            theme={theme}
            onChangeText={(text) => this.setState({ email: text, username: new sha.sha256().update(text).digest('hex') })}
          />
          <Password
            theme={theme}
            onChangeText={(text) => this.setState({ password: text })}
          />
          <Button
            title={I18n.get('Sign Up')}
            onPress={this.signUp}
            disabled={!this.state.username || !this.state.password}
          />
        </View>
        <Footer theme={theme} onStateChange={this.changeState} />
        <ErrorRow theme={theme}>{this.state.error}</ErrorRow>
      </View>
    );
  }
}

Overridden ConfirmSignup.js:

import React from 'react';
import { I18n } from 'aws-amplify';
import { ConfirmationCode, ConfirmSignUp as CoreConfirmSignUp, Email, ErrorRow, Header, LinkCell } from 'aws-amplify-react-native';
import { Button, View } from 'react-native';
import sha from 'sha.js';

const Footer = (props) => {
  const { theme, onStateChange } = props;
  return (
    <View style={theme.sectionFooter}>
      <LinkCell theme={theme} onPress={() => onStateChange('signIn')}>
        {I18n.get('Back to Sign In')}
      </LinkCell>
    </View>
  )
}

export default class ConfirmSignUp extends CoreConfirmSignUp {
  showComponent(theme) {
    return (
      <View style={theme.section}>
        <Header theme={theme}>{I18n.get('Confirm Sign Up')}</Header>
        <View style={theme.sectionBody}>
          <Email
            theme={theme}
            value={this.state.email}
            onChangeText={(text) => this.setState({ username: new sha.sha256().update(text).digest('hex') })}
          />
          <ConfirmationCode
            theme={theme}
            onChangeText={(text) => this.setState({ code: text })}
          />
          <Button
            title={I18n.get('Confirm')}
            onPress={this.confirm}
            disabled={!this.state.username || !this.state.code}
          />
          <Button
            title={I18n.get('Resend a Code')}
            onPress={this.resend}
            disabled={!this.state.username}
          />
        </View>
        <Footer theme={theme} onStateChange={this.changeState} />
        <ErrorRow theme={theme}>{this.state.error}</ErrorRow>
      </View>
    );
  }
}

Then you can pass in those overridden components, along with the default components for the other screens, into the withAuthenticator HOC like in the example here: https://github.com/aws/aws-amplify#3-override-default-authentication-screens.

If you were to diff those overridden components against the default ones, the only real differences are the lines with sha in them (specifically the onChangeText prop on each <Email/> component).

Note that this relies on the fact that Cognito User Pools allows for login using either username or email, so your end user can use email address on the SignIn page and it will "just work" without any changes. Plus the end user doesn't need to know the username hash (obviously).

@dillonbailey
Copy link

@rlmartin @ldgarcia - thanks for the options guys! 👍

The only issue I'm running into now, and this may be related to https://github.com/aws/awsmobile-cli - but setting email as an alias doesn't yet seem to be an option if you are using Mobile Hub.

Are either of you guys using Mobile Hub and having any success with this?

@rlmartin
Copy link
Contributor Author

I've been using Mobile Hub, but not the cli. I've been able to set it up without a problem to allow for login using either email or username.

@dillonbailey
Copy link

Awesome - thanks @rlmartin - on further reading it looks like setting the username with the UUID is the key to making this work!

@ldgarcia
Copy link
Contributor

ldgarcia commented Feb 21, 2018

@dillonbailey this is my user pool configuration:

screen shot 2018-02-21 at 12 07 46 pm

With the approach I mentioned, you don't need to generate the UUID yourself, Cognito does it (stores it in the sub attribute).

@dillonbailey
Copy link

@ldgarcia interesting - whether I go via CLI or GUI, it ends up force checking the Username radio button...opening a case with AWS

@codercodingthecode
Copy link

I'm facing a similar issue, User management created by Mobile Hub won't allow changes on Cognito attributes. It won't allow sign in with email or assign an email to username on signup.
Disappointing so far :/

@dillonbailey
Copy link

@andythedandyone I’ve got an open case with support on this, will let you know how I get on.

@elorzafe
Copy link
Contributor

Hi @rlmartin @dillonbailey @ldgarcia @andythedandyone thanks for your feedback!
On awsmobile-cli you can do the following.

  1. if you don't have the feature enabled run:
    awsmobile user-signin enable -p
    and then:
    1.1)
    -Go to advance settings
    -Cognito UserPools
    -Select how are users are going to login: Email
    -Password length
    -Password requirements

finally
awsmobile push

  1. if you have enabled user-signin and cognito is the only signin method run:
    awsmobile user-signin disable
    awsmobile push(this will delete your UserPool)
    and then repeat steps 1)

  2. if you have enabled user-signin and cognito is not the only signin method
    awsmobile user-signin configure. Select cognito UserPools, then disable it,
    awsmobile push (this will delete your UserPool)
    awsmobile user-signin configure.
    then repeat from step 1.1)

Please let me know if you have any issues with this

@codercodingthecode
Copy link

@elorzafe I did that when I integrated cognito to mobile hub. I chose to login by email, pwd requirements/length. There is a print screen of what I get with this setup I mentioned here.(see below)
However, I still get stuck at the things I mentioned above. I will give it another try thru the cli instead the web interface MH.
But why not allow to change attributes for the user pool?
The solution I found for the meantime was to follow one of the posts above and hash the email to username.

    signUp = () => {
        sha256(this.state.email.toLowerCase()).then(data => {
            Auth.signUp({
                username: data,
                password: this.state.password,
                attributes: {
                    email: this.state.email.toLowerCase(),
                    phone_number: 
                }
            }).then(data => {
                this.props.navigation.navigate('Login');
            }).catch(err => console.log('errors sign up  ', err));
        })
    }

and login

    signIn = () => {
        sha256(this.state.email.toLowerCase()).then(data => {
            Auth.signIn(data, this.state.password).then(data => {
                Keyboard.dismiss();
                setTimeout(() => {
                    this.props.navigation.navigate('TopBar');
                }, 2000);
            }).catch(err => console.log('error was there => ', err))
        }).catch(err => console.log('could not hash ', err));
    }

image

@mwarger
Copy link

mwarger commented Mar 7, 2018

@dillonbailey I'm facing the same issue wherein Cognito isn't letting me select the email address as username. Any update from support?

@dillonbailey
Copy link

dillonbailey commented Mar 7, 2018

@mwarger feedback from support was the following:

Thank you for the information and feedback. I have read through the provided resources and tried out a few different options. At the moment, the ability to make changes to the standard attributes for a Cognito User Pool once it has been created is not available. As a result of this, you will not be able to have Mobile Hub create a user pool and make the subsequent changes in order to provide for the described use case.

I do see though that a feature request for this functionality has been raised already and I have added your case as an additional request for this feature. I do not have an ETA on the delivery of this feature. I will suggest to keep an eye on https://aws.amazon.com/new/ for information on new features and capabilities added.

As a workaround I can suggest 2 possible scenarios. The first and most straightforward is to create the User Pool manually or via Cloud Formation [AWS::Cognito::UserPool:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpool.html] and not with Mobile Hub. All the code still needs to be implemented within the application to deal with Cognito as usual even with creating a pool with Mobile Hub. If it has, remove the pool from the Mobile Hub configuration and replace the existing required references within the application with the new pool information.

One could possibly consider making use of another Identity Provider via SAML 2.0 and federate identities with the Mobile Hub created user pool. This in turn will allow full control on what information a user can use for registration and login but will require further work as far as the Identity Provider is concerned. Authentication will take place against the Identity Provider and not via the User Pool which might defeat the purpose. See https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-saml-idp.html for full description on implementing this with Cognito User Pools.

@mlabieniec mlabieniec added the feature-request Request a new feature label Apr 2, 2018
@mlabieniec mlabieniec added Auth Related to Auth components/category Cognito Related to cognito issues and removed enhancement labels Apr 13, 2018
@uclaeamsavino
Copy link

uclaeamsavino commented Oct 24, 2018

I can even sign up through the client-side component generated when using the withAuthenticator HOC. But it seems that the user still has to enter email twice. If it could just not show one of these fields it would be perfect:

image

@andreupifarre
Copy link

Any updates on this? I am having the same issue, I don't want to show the username field on my amplify signup form.

@rjbaker
Copy link

rjbaker commented Dec 4, 2018

+1 This is fairly common use case and requires a comprehensive workaround instead of a simple prop to configure the component without the username field.

@lotjuh
Copy link

lotjuh commented Dec 16, 2018

+1 Facing the same issue. I want the username to be automatically set to the user's email address. Don't want to need the user to fill out their email twice...

@mapkbalaji
Copy link

@dillonbailey this is my user pool configuration:

screen shot 2018-02-21 at 12 07 46 pm

With the approach I mentioned, you don't need to generate the UUID yourself, Cognito does it (stores it in the sub attribute).

How do you make this configuration using cli?

@askpatrickw
Copy link

@dillonbailey this is my user pool configuration:
screen shot 2018-02-21 at 12 07 46 pm
With the approach I mentioned, you don't need to generate the UUID yourself, Cognito does it (stores it in the sub attribute).

How do you make this configuration using cli?

You can see how to do it here: aws-amplify/amplify-cli#102 (comment)

It does require manual config file editing before you push your config.

@fcwheeler
Copy link

I am using the SignUpConfig prop for Authenticator to hide the username and phone_number fields.

<Authenticator  signUpConfig={{ hiddenDefaults:['username','phone_number'],signUpFields: [{
            label:"Email",
            key:"email",
            required: true,
            displayOrder: 1,
            type: 'string',
            custom: false
          },        
          {
            label:"Password",
            key:"password",
            required: true,
            displayOrder: 1,
            type: 'password',
            custom: false
          }]}
            
          }>

Maybe this is a recent enhancement, or i am not understanding the question

@undsoft
Copy link

undsoft commented Mar 22, 2019

@fcwheeler
Your config gives me a validation error "Username is required" or something like that.

This works for me:

{
  hideAllDefaults: true,
  signUpFields: [
    {
      label:"Email",
      key:"username",
      required: true,
      displayOrder: 1,
      type: 'email',
      custom: false
    },
    {
      label:"Password",
      key:"password",
      required: true,
      displayOrder: 2,
      type: 'password',
      custom: false
    }
  ]
}

The login will still say 'username' though.

@navraj007in
Copy link

Hi,
I am using amplify to create a sign up form. however i need a custom field called user type which will have 2 possible values(Employer/Contractor). This should be input through radio button and its essential to capture at the time of sign up. I tried to look into signupFields options and type can have only 3 values as of now: string, number and date. is there a way to incorporate Fields like these?
even the gender field needs a radio button rather than a text field.

Would like to know if its already a feature or yet to be developed?

Thank you.

@uclaeagit
Copy link

Can you make it a hidden field that resolves from the radio button selection using Javascript?

@powerful23
Copy link
Contributor

Hi All, the feature is implemented in the beta version of amplify UIs:

aws-amplify-react@beta
aws-amplify-react-native@beta
aws-amplify-angular@beta
aws-amplify-vue@beta

The docs is in: aws-amplify/docs#622
Basically you can change the default sign in or sign up component by passing the usernameAttributes props in the Authenticator. For example, in React:

import { Authenticator } from 'aws-amplify-react';

class App extends React.Component {
    //.....
    render() {
         return (
                <Authenticator usernameAttributes="email"/>
         );
    }
}

Welcome any feedback. Thanks.

@rtuin
Copy link

rtuin commented Jul 30, 2019

This looks good 👍 I see it's in master now.

For those ending up here via search engines, here's the link to the docs: https://aws-amplify.github.io/docs/js/react#sign-upin-with-emailphone-number

This worked for me to get a sign up component with only email address + password fields:

export default withAuthenticator(App, {
  usernameAttributes: 'email',
  signUpConfig: {
    hiddenDefaults: ['phone_number']
  }
});

@jimpala
Copy link

jimpala commented Aug 20, 2019

Unless I'm missing something email/phone as username still not supported for Auth.signUp()and Auth.signIn() methods while the user pool is set up that way.
I can sign up fine, but I think it needs the generated UUID username for the sign in.

Should I create a separate issue?

@plisitza
Copy link

affecting me too. the fact that Cognito allows this but libraries do not is odd/wrong. this is a common use case and not everyone wants to use the stock components...

@haverchuck
Copy link
Contributor

@jpyne17 @plisitza I believe that the use of email or phone number is supported with Auth.signIn. This method accepts a parameter called 'usernameOrSignInOpts'. If the usernameAttribute is set to 'email' (i.e. you are using an email address as the username), passing the email as this parameter should work (I just confirmed it). If it is not working, please details the exact behavior you're experiencing.

@sammartinez
Copy link
Contributor

In looking at the original feature request, I am seeing that this is now complete. Resolving this feature request. @rlmartin Please let us know if something isnt complete.

@jpyne17 @plisitza Please open up a separate issue with us if you are still experiencing issues after @haverchuck comment.

aws-amplify automation moved this from Backlog to @beta Jan 21, 2020
@nihp
Copy link

nihp commented Mar 17, 2020

I have enabled both Email and phone number.

But I only receiving the code in Phone number. I not get any acknowledgement or any code in my email?

I need to know why the code not received in my mail?

@John867530nine
Copy link

John867530nine commented Mar 21, 2020

I have enabled both Email and phone number.

But I only receiving the code in Phone number. I not get any acknowledgement or any code in my email?

I need to know why the code not received in my mail?

It's a feature, not a bug. Ref:
https://docs.aws.amazon.com/cognito/latest/developerguide/signing-up-users-in-your-app.html

@hutch120
Copy link

hutch120 commented Mar 22, 2020

Amplify is looking great, but some of these default settings boggle the mind.

A simple email and password login is the most common signup process in the world. No one wants to bother their users to have to enter some weird username (which is most likely their email anyway) or phone number, or any one of the 20 other weird fields (what on earth is zoneinfo?). Also, no one is going to put their phone number into a signup form for 99.99% of websites in the world.

I strongly suggest adding the following example to the doco to save almost everyone who wants to use this component to have to search this issue thread. (OR better yet, make it the default behaviour)

The code below was the only way I could get the react sign up component to display only email address and password fields. ( Thanks @rtuin )

export default withAuthenticator(App, {
  usernameAttributes: 'email',
  signUpConfig: {
    hiddenDefaults: ['phone_number']
  }
});

image

@nihp
Copy link

nihp commented Mar 23, 2020

@johnmesotech Thanks.

I have another one clarification. Can you clarify? The error messages are retaining in all the screens if I revisit that screen after creating or it will shows an error with wrong input.

How can I change the notice of my confirmation code?

@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 *-help channels or Discussions for those types of questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 12, 2021
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
No open projects
aws-amplify
  
@beta
Development

No branches or pull requests