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

aws_cognito_identity_pool_id missing in the final aws-exports.js #12520

Closed
5 tasks done
mkbctrl opened this issue Apr 24, 2023 · 16 comments
Closed
5 tasks done

aws_cognito_identity_pool_id missing in the final aws-exports.js #12520

mkbctrl opened this issue Apr 24, 2023 · 16 comments
Assignees
Labels
auth Issues tied to the auth category of the CLI pending-response Issue is pending response from the issue author pending-triage Issue is pending triage transferred This issue was transferred from another Amplify project

Comments

@mkbctrl
Copy link

mkbctrl commented Apr 24, 2023

Before opening, please confirm:

  • I have checked to see if my question is addressed in the FAQ.
  • I have searched for duplicate or closed issues.
  • I have read the guide for submitting bug reports.
  • I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
  • I have removed any sensitive information from my code snippets and submission.

App Id

NEW_APP

AWS Region

us-east-1

Amplify Hosting feature

Environment variables, Frontend builds

Describe the bug

While documenting the Cognito setup flow for my project documentation I stumbled upon an issue where using CLI for initial setup with social providers fails to include the aws_cognito_identity_pool_id in the final aws-exports.js output.

Below I included the images of choices I made while settings up the environment from scratch.

Funny thing is that last week, when running the wizard, the final output did include the aws_cognito_identity_pool_id. I didn't document the flow that, but I am sure I was using the social provider auto setup as well, I would it expect to always include the id in the final config object

Expected behavior

Instead of aws-exports looking like this:

const awsmobile = {
  aws_project_region: 'us-east-1',
  aws_cognito_region: 'us-east-1',
  aws_user_pools_id: ':Redacted',
  aws_user_pools_web_client_id: ':Redacted',
  oauth: {
    domain: ':Redacted',
  },
  aws_cognito_username_attributes: ['EMAIL'],
  aws_cognito_social_providers: [],
  aws_cognito_signup_attributes: ['EMAIL'],
  aws_cognito_mfa_configuration: 'OFF',
  aws_cognito_mfa_types: [],
  aws_cognito_password_protection_settings: {
    passwordPolicyMinLength: 8,
    passwordPolicyCharacters: [
      'REQUIRES_LOWERCASE',
      'REQUIRES_UPPERCASE',
      'REQUIRES_NUMBERS',
      'REQUIRES_SYMBOLS',
    ],
  },
  aws_cognito_verification_mechanisms: ['EMAIL'],
}

it should look like (include aws_cognito_identity_pool_id: ':Redacted',:

const awsmobile = {
  aws_project_region: 'us-east-1',
  aws_cognito_region: 'us-east-1',
  aws_user_pools_id: ':Redacted',
  aws_user_pools_web_client_id: ':Redacted',
  aws_cognito_identity_pool_id:
    ':Redacted',
  oauth: {
    domain: ':Redacted',
  },
  aws_cognito_username_attributes: ['EMAIL'],
  aws_cognito_social_providers: [],
  aws_cognito_signup_attributes: ['EMAIL'],
  aws_cognito_mfa_configuration: 'OFF',
  aws_cognito_mfa_types: [],
  aws_cognito_password_protection_settings: {
    passwordPolicyMinLength: 8,
    passwordPolicyCharacters: [
      'REQUIRES_LOWERCASE',
      'REQUIRES_UPPERCASE',
      'REQUIRES_NUMBERS',
      'REQUIRES_SYMBOLS',
    ],
  },
  aws_cognito_verification_mechanisms: ['EMAIL'],
}

Reproduction steps

amplify init

amplify add auth

Screenshot 2023-04-24 at 10 18 39

Screenshot 2023-04-24 at 10 26 14

and afterwards running:

amplify env checkout dev

Build Settings

No response

Log output

# Put your logs below this line


Additional information

No response

@mkbctrl mkbctrl added bug Something isn't working pending-triage Issue is pending triage labels Apr 24, 2023
@ghost
Copy link

ghost commented Apr 24, 2023

Hi @mkbctrl 👋🏽 thanks for raising this issue. I'm transferring this to the Amplify CLI repo for better visibility.

@ghost ghost transferred this issue from aws-amplify/amplify-hosting Apr 24, 2023
@josefaidt josefaidt added transferred This issue was transferred from another Amplify project and removed bug Something isn't working labels Apr 24, 2023
@mkbctrl
Copy link
Author

mkbctrl commented Apr 25, 2023

update:

We went with manual setup today. Same issue, no identity id in the output:

const awsmobile = {
    "aws_project_region": "us-east-1",
    "aws_cognito_region": "us-east-1",
    "aws_user_pools_id": ":redacted",
    "aws_user_pools_web_client_id": ":redacted",
    "oauth": {
        "domain": ":redacted.auth.us-east-1.amazoncognito.com",
        "scope": [
            "phone",
            "email",
            "openid",
            "profile",
            "aws.cognito.signin.user.admin"
        ],
        "redirectSignIn": "http://localhost:3000/api/auth/callback/cognito/",
        "redirectSignOut": "http://localhost:3000/api/auth/callback/cognito/",
        "responseType": "code"
    },
    "federationTarget": "COGNITO_USER_POOLS",
    "aws_cognito_username_attributes": [
        "EMAIL"
    ],
    "aws_cognito_social_providers": [
        "FACEBOOK",
        "GOOGLE"
    ],
    "aws_cognito_signup_attributes": [
        "EMAIL",
        "NAME"
    ],
    "aws_cognito_mfa_configuration": "OFF",
    "aws_cognito_mfa_types": [
        "SMS"
    ],
    "aws_cognito_password_protection_settings": {
        "passwordPolicyMinLength": 8,
        "passwordPolicyCharacters": []
    },
    "aws_cognito_verification_mechanisms": [
        "EMAIL"
    ]
};


export default awsmobile;

image-1

@mkbctrl
Copy link
Author

mkbctrl commented Apr 25, 2023

update 2: (success)
Going with manual configuration: User Sign-Up, Sign-In, connected with AWS IAM controls (Enables per-user Storage fea tures for images or other content, Analytics, and more) ended with federated pool id being present in the end.

remarks:

  • Why do you ask for facebook app id just to ask for it again couple of questions later?
  • Questions are frased differently, you have this feeling it's slightly different process overall + the number of deployed resources seems to be higher as well (not confirmed with data, subjective)

image (2)

@josefaidt
Copy link
Contributor

Hey @mkbctrl 👋 thanks for raising this! As you have noted, when creating an auth resource we will need to select the option "connected with AWS IAM controls..." in order to provision an Identity Pool. This is also created when choosing the "default" configuration options at the beginning of the amplify add auth prompt flow.

Questions are frased differently, you have this feeling it's slightly different process overall + the number of deployed resources seems to be higher as well (not confirmed with data, subjective)

I agree with you that this prompt flow is quite confusing, and is something that is top of mind for future iterations of the CLI!

@josefaidt josefaidt self-assigned this Apr 25, 2023
@josefaidt josefaidt added auth Issues tied to the auth category of the CLI pending-response Issue is pending response from the issue author labels Apr 25, 2023
@mkbctrl
Copy link
Author

mkbctrl commented Apr 27, 2023

By default you mean default with or without the social provider? It's kind of weird if it's for bare default, cause I would assume that that's a scenario where you don't need federated sign in 🤔

...and for the version with SP it didn't work (initial issue) unless I did smth wrong (can you have a look at the path I chose?)

@github-actions github-actions bot removed the pending-response Issue is pending response from the issue author label Apr 27, 2023
@josefaidt
Copy link
Contributor

Hey @mkbctrl by "default" I am referring to the first prompt for amplify add auth where it prompts for "default config", "default with social...", or "manual configuration". In the path you posted, when choosing "manual configuration" we must specify the option that is "connected with IAM controls"

As an example, using the "default with social provider" option will create the identity pool and associated ID in src/aws-exports.js

 Do you want to use the default authentication and security configuration? Default configu
ration with Social Provider (Federation)
 Warning: you will not be able to edit these selections. 
 How do you want users to be able to sign in? Email
 Do you want to configure advanced settings? No, I am done.
 What domain name prefix do you want to use? 12520a5f00760-a5f00760
 Enter your redirect signin URI: http://localhost:3000/
? Do you want to add another redirect signin URI No
 Enter your redirect signout URI: http://localhost:3000/
? Do you want to add another redirect signout URI No
 Select the social providers you want to configure for your user pool: Facebook
  
 You've opted to allow users to authenticate via Facebook.  If you haven't already, you'll
 need to go to https://developers.facebook.com and create an App ID. 
 
 Enter your Facebook App ID for your OAuth flow:  fakeappid
 Enter your Facebook App Secret for your OAuth flow:  fakeappsecret
✅ Successfully added auth resource 12520a5f00760 locally

image

@josefaidt josefaidt added the pending-response Issue is pending response from the issue author label Apr 28, 2023
@mkbctrl
Copy link
Author

mkbctrl commented May 15, 2023

Thank you @josefaidt for explaining it in detail. I have much better understanding of the overall solution right now. I followed the same flow as you "default with social provider", and it did create one user pool, and one federated identities pool.

238313534-5bebad2f-bc9d-4755-a966-2267f9afad0a

When visiting federated identities pool settings you can notice that the connection to user pool is established:
Screenshot 2023-05-15 at 12 02 11

but for the facebook, there is nothing. I would expect otherwise:
Screenshot 2023-05-15 at 12 02 18

especially that, when trying to sign in using Facebook I am getting the following error:

Error during federated sign-in: NotAuthorizedException: Token is not from a supported provider of this identity pool.

Not sure whether it's a bug or a feature, but as an end user I would expect it work out of the box, or get notified in the end of the process what should I do next.

After entering the id manually in the federated identities pool settings, next sign in was successful.
Screenshot 2023-05-15 at 12 09 43

but the problem I am currently stuck with is the difference in the response shape between the regular signIn and federatedSignIn. The idToken is missing in the federated response, which makes my api calls return 401 status (unauth)

I think I understand (thanks to: aws-amplify/amplify-js#703), that Cognito User Pool is technically speaking very similar to Federated Identities Pool, and they are entirely separate things. If I sign in with facebook, the user will be added to federated pool, and the cognito user pool won't be aware about the fact.

However (I can't find the source atm), I googled, that when you connect the Cognito User Pool and Federated Identities User Pool, the federatedSignIn should return you idToken same as with regular signIn method (which I also believe happen when you are using you hosted UI - in my project I can't do that). Also I read that Cognito will handle cases like creating a user inside the Cognito User Pool if an email that just popped out through federated sign in does not exist yet.

After checking up the federated pool settings (screens above) I consider those user pools as connected. Am I wrong to assume that?

The attribute mapping is set as well:
image

Here the chunk of code handling this process (I am using next-auth to setup FB):

// profile and tokens come from next-auth
async profile(profile, tokens) {
        try {
          if (!tokens.expires_at || !tokens.access_token) {
            throw new Error('Facebook provider error: missing tokens')
          }

          const response = await Auth.federatedSignIn(
            'facebook',
            { token: tokens.access_token, expires_at: tokens.expires_at },
            { name: profile.name, email: profile.email }
          )
          
          const user = await Auth.currentAuthenticatedUser()

          console.log('user', user)
          console.log('response', response)

user:

{
  id: 'us-east-1:redacted',
  name: 'redacted',
  email: 'redacted',
  token: 'redacted'
}

response

{
  identityId: 'us-east-1:redacted',
  accessKeyId: 'ASIAredacted',
  secretAccessKey: 'yroredacted',
  sessionToken: 'redacted',
  expiration: 2023-05-15T11:07:53.000Z,
  authenticated: true
}

So my question to you @josefaidt , can you confirm it? And if that's the case, what my current setup is missing to make it work? (The only thing added as an extra on top of default output was the FB app id)

Thinking out loud:

  1. Should I setup a lambda, that will create Cognito User Pool if I sign up with facebook?
  2. Should I setup HUB listener and catch and event that will have the idToken in the payload?
  3. Should I just ask the backend team to make api recognize different tokens, and this is the way it should be handled (thus considered best practice)?

@github-actions github-actions bot removed the pending-response Issue is pending response from the issue author label May 15, 2023
@josefaidt
Copy link
Contributor

josefaidt commented May 16, 2023

Hey @mkbctrl what were the steps taken prior to noticing the Facebook credentials were missing? I was not able to reproduce that behavior when updating an existing auth resource with the social config and fake Facebook credentials
image

However I did notice these are not also in the Identity Pool
image

From the code snippet, are you using next-auth on top of Cognito by chance?

// profile and tokens come from next-auth

Do you see success from calling without passing the additional details to Auth.federatedSignIn? https://docs.amplify.aws/lib/auth/social/q/platform/js/#setup-frontend

@josefaidt josefaidt added the pending-response Issue is pending response from the issue author label May 16, 2023
@mkbctrl
Copy link
Author

mkbctrl commented May 16, 2023

Since I was documenting the entire flow for my team all my steps were recorded. I started from scratch by running amplify init:
Screenshot 2023-05-16 at 21 07 07

afterwards I checked if the app exist:
Screenshot 2023-05-16 at 21 07 11

once I was sure the project was initiated I run all the steps mentioned above, which is running the next development server locally, trying the facebook sign in by hand, running into issue that it's not supported (NotAuthorizedError mentioned above as well), fixing it by adding the FB app id to the Identity Pool, and trying again.

Once I noticed I have different sets of tokens (again), and that idToken is still missing, I decided to post my findings here hoping your knowledge and experience will unstuck me :)

Regarding next-auth, you are correct. I am running it on top of Cognito. Here is my next-auth configuration file:

export const authOptions: NextAuthOptions = {
  debug: process.env.NODE_ENV !== 'production',
  session: {
    strategy: 'jwt',
    maxAge: getAuthSessionLength(),
  },
  // https://next-auth.js.org/configuration/providers/oauth
  providers: [
    CredentialsProvider({
      id: 'credentials',
      name: 'Sign in with email',
      credentials: {
        username: { label: 'email', type: 'text' },
        password: { label: 'Password', type: 'password' },
      },
      authorize: authAuthorizeCredentials,
    }),
    CredentialsProvider({
      id: 'credentials-auto-login',
      name: 'Create session from token',
      // @ts-ignore
      authorize: authAuthorizedAutologin,
    }),
  // WIP
   FacebookProvider<FacebookProviderProps>({
      clientId: 'redacted',
      clientSecret: 'redacted',
      async profile(profile, tokens) {
        try {
          if (!tokens.expires_at || !tokens.access_token) {
            throw new Error('Facebook provider error: missing tokens')
          }

          // await Auth.signOut()

          console.log(profile)

          const response = await Auth.federatedSignIn(
            'facebook',
            { token: tokens.access_token, expires_at: tokens.expires_at },
            { name: profile.name, email: profile.email }
          )
          const user = await Auth.currentAuthenticatedUser()
          const session = await Auth.currentSession()

          console.log('user', user)
          console.log('response', response)
          console.log('session', session)

          const { sessionToken, expiration } = response

          if (!expiration) {
            throw new Error('Facebook provider error: missing expiration date')
          }

          return {
            email: '[email protected]',
            id: profile.id,
            uid: profile.id,
            idToken: sessionToken,
            idTokenExpiryDate: Date.now() + expiration.getTime() * 1000,
            refreshToken,
            // TODO: handle onboarding check
            isOnboarded: true,
            error: undefined,
          }
        } catch (error) {
          console.error('Error during federated sign-in:', error)
          return null
        }
      },
    }),
  ],
  pages: {
    signIn: PublicPath.SignIn,
    signOut: PublicPath.SignIn,
    error: PublicPath.SignIn,
  },
  // docs: https://next-auth.js.org/configuration/callbacks
  callbacks: {
    signIn: authCallbackSignIn,
    jwt: authCallbackJwt,
    session: authCallbackSession,
  },
  events: {
    signOut: authEventSignOut,
  },
}

authAuthorizeCredentials is using Cognito signIn (and works well), whereas authAuthorizedAutologin creates session based on Hub autologin event and creates the session on the fly.

Having Google and Facebook on top of that is currently my dream :D

Edit 1:
here is also the contents of my aws-exports.js:

/* eslint-disable */
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.

const awsmobile = {
    "aws_project_region": "us-east-1",
    "aws_cognito_identity_pool_id": "us-east-1:redacted",
    "aws_cognito_region": "us-east-1",
    "aws_user_pools_id": "us-east-redacted",
    "aws_user_pools_web_client_id": "redacted",
    "oauth": {
        "domain": "redacted-dev.auth.us-east-1.amazoncognito.com",
        "scope": [
            "phone",
            "email",
            "openid",
            "profile",
            "aws.cognito.signin.user.admin"
        ],
        "redirectSignIn": "http://localhost:3000/",
        "redirectSignOut": "http://localhost:3000/",
        "responseType": "code"
    },
    "federationTarget": "COGNITO_USER_POOLS",
    "aws_cognito_username_attributes": [
        "EMAIL"
    ],
    "aws_cognito_social_providers": [
        "FACEBOOK"
    ],
    "aws_cognito_signup_attributes": [
        "EMAIL",
        "NAME"
    ],
    "aws_cognito_mfa_configuration": "OFF",
    "aws_cognito_mfa_types": [
        "SMS"
    ],
    "aws_cognito_password_protection_settings": {
        "passwordPolicyMinLength": 8,
        "passwordPolicyCharacters": []
    },
    "aws_cognito_verification_mechanisms": [
        "EMAIL"
    ]
};


export default awsmobile;

@github-actions github-actions bot removed the pending-response Issue is pending response from the issue author label May 16, 2023
@mkbctrl
Copy link
Author

mkbctrl commented May 16, 2023

As per your suggestion, running it empty would require me to create entirely different setup. Currently the place where I am executing the code is server-side (nextjs api endpoint), and federatedSignIn requires a window to be operational.

Still, just for experiment sake I attached function Auth.federatedSignIn() to a button and clicked it. Hosted UI opened, I was able to click on the Facebook button, and I got succefully redirected back to my app with the following query params attached to the url:

http://localhost:3000/access/sign-in?code=redacted-ceed-4c7c-b20b-9d32ba0ac82d&state=redactedKMUn4kA8wG9YbmbMO6KWUCJyC#_=_

surprise, surprise I also found a new arrival in my Cognito User Pool users list:
image

How is that possible?! 🤔 🤔 🤔

So basically running federatedSignIn() with params produces entirely different outcome (user is added to identity pool) than running it empty (user is added to user pool) 🤔

image

the redirect was accompanied by the failed 400 call:

Request URL: https://cognito-identity.us-east-1.amazonaws.com/
Request Method: POST
Status Code: 400 
Remote Address: 54.152.6.52:443
Referrer Policy: strict-origin-when-cross-origin

with the following payload:

{IdentityPoolId: "us-east-1:redacted-b373-4aa1-81fe-efd0a6f3a710",…}
IdentityPoolId
: 
"us-east-1:redacted"
Logins
: 
{cognito-idp.us-east-1.amazonaws.com/us-east-: ""}

@mkbctrl
Copy link
Author

mkbctrl commented May 16, 2023

I tried to use Hub listener in hopes to catch some events, unfortunately after upon redirect the Post 400 call is sometimes issued before the Hub listener is initiated (I am doing it inside _app.tsx so at the very top) , which leads to sometimes catching an event and sometimes not.

The events I was able to listen to were about failure when getting back from cognito hosted UI.

image

@josefaidt josefaidt added the investigating This issue is being investigated label May 16, 2023
@josefaidt
Copy link
Contributor

Hey @mkbctrl wanted to follow up and mention that I am still investigating this use case with next-auth/auth.js on top of Cognito, but I touched base with our friends over at amplify-js and it is confirmed that when manually passing the user credentials as the second and third arguments of federatedSignIn it will not create a Cognito-native user. However, it is possible to link these federated identities to Cognito-native users, which I believe next-auth does by default when using a database provider. Creating the federated users and linking to Cognito-native users is what I am investigating for this use case.

@mkbctrl
Copy link
Author

mkbctrl commented Jun 1, 2023

Hey @josefaidt, thanks for your effort. Do you have any news maybe? I will investigate the account linking as you suggest. Will keep you posted about any findings.

@josefaidt
Copy link
Contributor

Hey @mkbctrl apologies for the delay here! Have you found success with next-auth on Cognito? I noticed there is also now auth.js, however this would typically be used on top of a database in place of Cognito. Out of curiosity, what is the intended use case for using next-auth/auth.js on top of Cognito? Would you mind filing an issue in our docs repo requesting a guide for this with those details? https://github.com/aws-amplify/docs/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc

@josefaidt josefaidt added pending-response Issue is pending response from the issue author and removed investigating This issue is being investigated labels Oct 3, 2023
@josefaidt
Copy link
Contributor

Closing due to inactivity

@josefaidt josefaidt closed this as not planned Won't fix, can't repro, duplicate, stale Feb 2, 2024
Copy link

github-actions bot commented Feb 2, 2024

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auth Issues tied to the auth category of the CLI pending-response Issue is pending response from the issue author pending-triage Issue is pending triage transferred This issue was transferred from another Amplify project
Projects
None yet
Development

No branches or pull requests

2 participants