aws-amplify / amplify-cli

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development.
Apache License 2.0
2.81k stars 821 forks source link

How to allow users to login using preferred_username through CLI? #9307

Closed hackrx closed 2 years ago

hackrx commented 2 years ago

Before opening, please confirm:

How did you install the Amplify CLI?

No response

If applicable, what version of Node.js are you using?

No response

Amplify CLI Version

7.6.2

What operating system are you using?

Mac

Amplify Categories

auth

Amplify Commands

push, update

Describe the bug

Right now, when we add an auth, this option is prompted, and it can't be changed later after deployment: image I want to allow my users to login using the preferred_username, I know we can set it when user first signup using postConfirmation trigger, then we can set username as sub value, and preferred_username as what userName he has entered, but the issue is, suppose user updates his username (which indirecly only updates his pref_username), now he will not be able login again using this pref_username, because in cognito console, the configuration is set like this: image

Three options are not ticked, which will not allow users to login using the set preferred_username

One more thing, I want to allow users to login/sign-up using Google, but if I choose preferred_username as required attribute, it doesn't allow me to add Google as social provider, instead it should prompt dev. to set preSignup function, to set pref_username equals to verified email.

 Select the social providers you want to configure for your user pool: (Press <space> to select, <a> to toggle all, <i> to invert
 selection)
 - Facebook (Your userpool is configured to require preferred_username, which cannot be retrieved from Facebook)
 - Google (Your userpool is configured to require preferred_username, which cannot be retrieved from Google)
 - Login With Amazon (Your userpool is configured to require preferred_username, which cannot be retrieved from Login With Amazon
)
 - Sign in with Apple (Your userpool is configured to require preferred_username, which cannot be retrieved from Sign in with App
le)

Expected behavior

Cli should have an option, to enable these ticks (allow login using username, email, or preferred_username), and dev. wants to add Google as a social provider, then cli should allow this.

Reproduction steps

With no social provider:

amplify add auth                                                        ✔ 
Using service: Cognito, provided by: awscloudformation

 The current configured provider is Amazon Cognito. 

 Do you want to use the default authentication and security configuration? Default configuration
 Warning: you will not be able to edit these selections. 
 How do you want users to be able to sign in? Username
 Do you want to configure advanced settings? Yes, I want to make some additional changes.
 Warning: you will not be able to edit these selections. 
 What attributes are required for signing up? Email, Preferred Username (This attribute is not supported by Facebook, Google, Log
in With Amazon, Signinwithapple.)
 Do you want to enable any of the following capabilities? 
✅ Successfully added auth resource wish9c8f0c30 locally

✅ Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud

and with social provider:

 amplify add auth                                                        ✔ 
Using service: Cognito, provided by: awscloudformation

 The current configured provider is Amazon Cognito. 

 Do you want to use the default authentication and security configuration? Manual configuration
 Select the authentication/authorization services that you want to use: User Sign-Up, Sign-In, connected with AWS IAM controls (E
nables per-user Storage features for images or other content, Analytics, and more)
 Provide a friendly name for your resource that will be used to label this category in the project: wish
 Enter a name for your identity pool. wish_pool
 Allow unauthenticated logins? (Provides scoped down permissions that you can control via AWS IAM) No
 Do you want to enable 3rd party authentication providers in your identity pool? Yes
 Select the third party identity providers you want to configure for your identity pool: Google

 You've opted to allow users to authenticate via Google.  If you haven't already, you'll need to go to https://developers.google.
com/identity and create an App ID. 

 Enter your Google Web Client ID for your identity pool:  71xcxxxxxx7.apps.googleusercontent.co
m
 Provide a name for your user pool: wish_pool
 Warning: you will not be able to edit these selections. 
 How do you want users to be able to sign in? Username
 Do you want to add User Pool Groups? No
 Do you want to add an admin queries API? No
 Multifactor authentication (MFA) user login options: OFF
 Email based user registration/forgot password: Enabled (Requires per-user email entry at registration)
 Specify an email verification subject: Your verification code
 Specify an email verification message: Your verification code is {####}
 Do you want to override the default password policy for this User Pool? No
 Warning: you will not be able to edit these selections. 
 What attributes are required for signing up? Email, Preferred Username (This attribute is not supported by Facebook, Google, Log
in With Amazon, Signinwithapple.)
 Specify the app's refresh token expiration period (in days): 30
 Do you want to specify the user attributes this app can read and write? No
 Do you want to enable any of the following capabilities? 
 Do you want to use an OAuth flow? Yes
 What domain name prefix do you want to use? wishaa1d36da-aa1d36da
 Enter your redirect signin URI: myapp://
? Do you want to add another redirect signin URI No
 Enter your redirect signout URI: myapp://
? Do you want to add another redirect signout URI No
 Select the OAuth flows enabled for this project. Authorization code grant
 Select the OAuth scopes enabled for this project. Phone, Email, OpenID, Profile, aws.cognito.signin.user.admin
 Select the social providers you want to configure for your user pool: (Press <space> to select, <a> to toggle all, <i> to invert
 selection)
 - Facebook (Your userpool is configured to require preferred_username, which cannot be retrieved from Facebook)
 - Google (Your userpool is configured to require preferred_username, which cannot be retrieved from Google)
 - Login With Amazon (Your userpool is configured to require preferred_username, which cannot be retrieved from Login With Amazon
)
 - Sign in with Apple (Your userpool is configured to require preferred_username, which cannot be retrieved from Sign in with App
le)

GraphQL schema(s)

```graphql # Put schemas below this line ```

Log output

``` # Put your logs below this line ```

Additional information

am I missing something? please correct me if my requirements are complicated.

lazpavel commented 2 years ago

Hi @hackrx, you can set the forceAliasAttributes flag in the amplify/cli.json to true before executing the amplify add auth. See more details here

hackrx commented 2 years ago

Hey @lazpavel, thanks for the follow-up, by following the link, I am able to set preferred_username as `aliasAttribute.

hackrx commented 2 years ago

Now, it is fine in console, it enabled both options, which I was expecting: image

But I also want to allow users to sign-in/sign-up using google auth, but cli is not allowing:

amplify update auth                                   ✔ 
Please note that certain attributes may not be overwritten if you choose to use defaults settings.
Using service: Cognito, provided by: awscloudformation
 What do you want to do? Update OAuth social providers
 Select the identity providers you want to configure for your user pool: (Press <space> to select, <a> to toggle all
, <i> to invert selection)
 - Facebook (Your userpool is configured to require preferred_username, which cannot be retrieved from Facebook)
 - Google (Your userpool is configured to require preferred_username, which cannot be retrieved from Google)
 - Login With Amazon (Your userpool is configured to require preferred_username, which cannot be retrieved from Logi
n With Amazon)
 - Sign in with Apple (Your userpool is configured to require preferred_username, which cannot be retrieved from Sig
n in with Apple)
lazpavel commented 2 years ago

Hi @hackrx, you're not allowed to select the social providers because you selected Preferred Username for the What attributes are required for signing up?. You should be able to use any social providers with the preferred_username as long as you select required signing attributes that are supported for the provider.

hackrx commented 2 years ago

I can set it using the console, but not using cli: image

The issue with this is, if next time, I will update anything, then it will remove the google federation from the respective pool.

hackrx commented 2 years ago

Hey @lazpavel, I tried this way:

  1. I deleted my auth, then again created with lambda trigger, and email as the only required attribute.
  2. I initialised preSignUp trigger for the lambda function.
  3. Hosted UI allows users to enter username + email + password for signUP.
  4. In my case I want to use sub as userName in cognito, and set sent userName as preferred_username.
  5. So I edited my presignUP lambda and modified the event object, like this ;
        const subUniq = uuidv4();
        event.request.userAttributes.preferred_username = event.userName;
        event.request.userAttributes.sub = subUniq;
        event.request.userName = subUniq;
        console.log("going to create a user with event.req: ");
        console.log(event.request);
        callback(null, event);

but I am facing Invalid user name. User name should be $username, because I am manipulating event.username in the preSignUp function, and if i am passing preferred_username at the time of sign-up, I am getting

 Enter correct parameters., underlyingException: com.amazonaws.services.cognitoidentityprovider.model.InvalidParameterException: Preferred username cannot be provided for unconfirmed account, since user pool is configured for preferred username alias

code which I am using for sign-up:

 Map<String, String> userAttributes = {
                          'email': 'tesst@gmail.com',
                          'preferred_username': "hackrx1"
                          // additional attributes as needed
                        };
                        SignUpResult res = await Amplify.Auth.signUp(
                            username: 'hackrx',
                            password: 'Test@123',
                            options: CognitoSignUpOptions(
                                userAttributes: userAttributes));

I want to achieve:

  1. Username should be 36 char long uniq value (==sub).
  2. Instead of userName, pass preferred_username, so that the user can update it, and use it for the next sign-in.
  3. Email id as required attribute (no issues with email ID).
lazpavel commented 2 years ago

Hi @hackrx, I believe you might be able to achieve what you need by configuring an userPool with preferred_username and without social providers, and then expand the userPool with social providers/do the mapping using amplify override auth.

See more details here

Trying to setup a mock application at the moment to confirm that this will solve the requirements

hackrx commented 2 years ago

can you please tell me how can I fulfill these requirements?

Username should be 36 char long uniq value (==sub).
Instead of userName, pass preferred_username, so that the user can update it, and use it for the next sign-in.
Email id as required attribute (no issues with email ID).

and in any platform (for eg. flutter) , if I am trying to sign up, then it says, username is required attribute.

Looking forward for your response 🙂 .

lazpavel commented 2 years ago

Hi @hackrx, sorry for such a late response.

You can:

  1. create an app by setting the forceAliasAttributes: true in the cli.json
  2. run amplify add auth and select Username for How do you want users to be able to sign in?
  3. run amplify override auth and manually add the social providers you want as follows in the override.ts
import { AmplifyAuthCognitoStackTemplate } from "@aws-amplify/cli-extensibility-helper";

export function override(resources: AmplifyAuthCognitoStackTemplate) {
  resources.userPool.aliasAttributes = ["preferred_username"];

  resources.addCfnResource(
    {
      type: "AWS::Cognito::UserPoolIdentityProvider",
      properties: {
        AttributeMapping: {
          preferredUsername: "email",
          email: "email"
        },
        ProviderDetails: {
          client_id: "test",
          client_secret: "test",
          authorize_scopes: "test",
        },
        ProviderName: "LoginWithAmazon",
        ProviderType: "LoginWithAmazon",
        UserPoolId: {
          Ref: "UserPool",
        },
      },
    },
    "amazon-social-provider"
  );
}
lazpavel commented 2 years ago

Please reopen if you still have issues

AsitDixit commented 2 years ago

@hackrx have you solved your issue?

lucasoares commented 1 year ago

@lazpavel hey! May you please provide the entire amplify auth add configuration for this case?

I'm trying for hours to implement the amplify configuration enabling users to sign in with both username and email and signup by manual form or by the social provider without success :(

Every time I try, something goes wrong and the signup doesn't behave as expected.

Thank you.

SNK47 commented 10 months ago

Hi lazpavel,How do I add all three alias attributes in AWS Cognito while creating AWS amplify add auth?

AddAuthCMD