aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.43k stars 2.13k forks source link

[amplify-js] Requests to cognito for authentication being made twice on Firefox #10272

Open karimtamerBW opened 2 years ago

karimtamerBW commented 2 years ago

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

Authentication

Amplify Categories

auth

Environment information

# Put output below this line System: OS: Windows 10 10.0.22000 CPU: (8) x64 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz Memory: 7.20 GB / 15.70 GB Binaries: Node: 12.22.12 - C:\Program Files\nodejs\node.EXE npm: 6.14.16 - C:\Program Files\nodejs\npm.CMD Browsers: Edge: Spartan (44.22000.120.0), Chromium (104.0.1293.70) Internet Explorer: 11.0.22000.120 npmPackages: @aws-amplify/storage: ^3.4.4 => 3.4.4 @emotion/react: ^11.6.0 => 11.9.0 @emotion/styled: ^11.6.0 => 11.8.1 @mui/icons-material: ^5.1.0 => 5.8.0 @mui/lab: ^5.0.0-alpha.54 => 5.0.0-alpha.82 @mui/material: ^5.1.0 => 5.8.0 @mui/styles: ^5.1.0 => 5.8.0 @mui/x-data-grid-pro: ^5.0.1 => 5.11.0 @sheerun/mutationobserver-shim: ^0.3.3 => 0.3.3 @testing-library/jest-dom: ^5.11.0 => 5.16.4 @testing-library/react: ^10.4.3 => 10.4.9 @testing-library/user-event: ^14.4.1 => 14.4.1 @types/google-map-react: ^2.1.0 => 2.1.7 @types/jest: ^24.0.0 => 24.9.1 @types/lodash: ^4.14.165 => 4.14.182 @types/node: ^12.0.0 => 12.20.52 (14.18.18) @types/react: ^17.0.34 => 17.0.45 @types/react-dom: ^17.0.11 => 17.0.17 @types/react-html-parser: ^2.0.2 => 2.0.2 @types/react-plotly.js: ^2.2.4 => 2.5.0 @types/react-router-dom: ^5.1.5 => 5.3.3 @typescript-eslint/eslint-plugin: 4.33.0 => 4.33.0 @typescript-eslint/parser: 4.33.0 => 4.33.0 (1.13.0, 3.10.1) apexcharts: ^3.24.0 => 3.35.2 aws-amplify: ^3.4.3 => 3.4.3 axios: ^0.21.0 => 0.21.4 (0.21.1) babel-eslint: 10.1.0 => 10.1.0 clsx: ^1.1.1 => 1.1.1 cypress: ^9.1.0 => 9.6.1 eslint-config-airbnb: ^19.0.1 => 19.0.4 eslint-config-prettier: 8.3.0 => 8.3.0 eslint-config-react-app: 6.0.0 => 6.0.0 eslint-import-resolver-typescript: 2.5.0 => 2.5.0 eslint-loader: 4.0.2 => 4.0.2 eslint-plugin-flowtype: 5.10.0 => 5.10.0 eslint-plugin-import: 2.25.3 => 2.25.3 (2.26.0) eslint-plugin-jsx-a11y: 6.5.1 => 6.5.1 eslint-plugin-prettier: 4.0.0 => 4.0.0 eslint-plugin-react: 7.27.1 => 7.27.1 (7.29.4) eslint-plugin-react-hooks: 4.3.0 => 4.3.0 (4.5.0) formik: ^2.2.9 => 2.2.9 formik-mui: ^4.0.0-alpha.3 => 4.0.0-alpha.3 formik-mui-lab: ^1.0.0-alpha.3 => 1.0.0-alpha.3 google-map-react: ^2.1.9 => 2.1.10 jest-canvas-mock: ^2.4.0 => 2.4.0 js-file-download: ^0.4.12 => 0.4.12 lodash: ^4.17.21 => 4.17.21 plotly.js: ^1.54.6 => 1.58.5 prettier: 2.4.1 => 2.4.1 (1.19.1) prettier-eslint: 13.0.0 => 13.0.0 (9.0.2) prettier-eslint-cli: 5.0.1 => 5.0.1 react: ^17.0.2 => 17.0.2 react-apexcharts: ^1.3.7 => 1.4.0 react-dom: ^17.0.2 => 17.0.2 react-dropzone: ^11.0.1 => 11.7.1 (10.2.2) react-html-parser: ^2.0.2 => 2.0.2 react-html-parser-demo: 0.0.0 react-json-view: ^1.20.5 => 1.21.3 react-material-ui-carousel: ^3.0.4 => 3.3.3 react-mui-dropzone: ^4.0.5 => 4.0.6 react-plotly.js: ^2.4.0 => 2.5.1 react-router-dom: ^5.2.0 => 5.3.2 react-scripts: 4.0.3 => 4.0.3 typescript: ^3.8.3 => 3.9.10 uuid: ^3.4.0 => 3.4.0 (3.3.2, 8.3.2) yup: ^0.32.11 => 0.32.11 npmGlobalPackages: @aws-amplify/cli: 9.2.1 npm: 6.14.16

Describe the bug

Hello!

I’m building a React App where I’m using the amplify-js library and Cognito for the Authentication. Every thing works normally on Google Chrome, however, I seem to be facing weird behavior on Mozilla Firefox where all the Cognito requests for authentication (Sign Up and Sign In) are made twice.

As a result, Cognito returns an error for the second unwanted request. For example if a user is signing up for the first time, the first request containing the username password credentials is sent and authenticated successfully, but the second “forced” request returns a 400 Bad Request error saying that the user already exists.

We are using

amplify-js v3.43.

The issue does not exist for Edge and Chrome, but does exist on Firefox. We have tried all different browser settings such as clearing cookies and cache, however, Cognito still receives two consecutive requests for Sign Up resulting in an error.

Here is a screenshot of the requests made on Firefox:

Request 1.png

Request 2.png

Here is the same exact operation done from Chrome

Untitled

Here’s the handler code for sign up:

const handleSubmit = async (
    values: SignValuesFields,
    setSubmitting: (isSubmitting: boolean) => void
  ) => {
    setError('');
    Auth.signUp({
      username: values.email,
      password: values.password,
    })
      .then(() => {
        history.push(urls.confirmCreateAccount, { email: values.email });
      })
      .catch((err: { code: string }) => {
        setError(translateCognitoError(err));
        setSubmitting(false);
      });
  };

Following is the amplify Config:

{
    "API": {
        "endpoints": [
            {
                                "custom_header": {
                                        "Authorization": "idToken"
                                },
                "name": "apiService",
                "endpoint": <endpoint>
                "region": "eu-west-1"
            }
        ]
    },
    "Auth": {
        "mandatorySignIn": true,
        "region": "eu-west-1",
        "userPoolId": <userPoolId>
        "userPoolWebClientId": <userPoolWebClientId>,
        "identityPoolId": <identityPoolId>,
        "measurementLocationsDocumentsBucket": <measurementLocationsDocumentsBucket>,
        "loggerFilesBucket": <loggerFilesBucket>
    },
    "Storage": {
        "AWSS3": {
            "bucket": <bucket>
            "region": "eu-west-1",
            "identityPoolId": <identityPoolId>
        }
    }
}

Following function adds the custom_header to the “API” → “endpoints” config:

custom_header: async () => {
    const session = await Auth.currentSession();
    return {
      Authorization: get(session, 'idToken.jwtToken'),
    };
  }

We also tried to verify all Cognito user pool settings.

We are not sure if this is a bug or the config is missing some setting.

Expected behavior

The expected behavior is simply sending the authentication request once!

Reproduction steps

  1. Set up Authentication with the Amplify API
  2. Open Firefox
  3. Try authentication

Code Snippet

// Put your code below this line.

Log output

``` // Firefox logs [DEBUG] 28:54.444 AuthClass - signUp validation data: null [ConsoleLogger.ts:99](file:///D:/Code/Brightwind/src/Logger/ConsoleLogger.ts) [DEBUG] 28:54.493 AuthClass - signUp attrs: Array [] [ConsoleLogger.ts:99](file:///D:/Code/Brightwind/src/Logger/ConsoleLogger.ts) [DEBUG] 28:54.493 AuthClass - signUp validation data: null [ConsoleLogger.ts:99](file:///D:/Code/Brightwind/src/Logger/ConsoleLogger.ts) XHRPOSThttps://cognito-idp.eu-west-1.amazonaws.com/ [HTTP/2 400 Bad Request 101ms] [DEBUG] 28:55.345 Hub - Dispatching to auth with Object { event: "signUp_failure", data: {…}, message: "karimfirefox1234@gmail.com failed to signup" } [ConsoleLogger.ts:99](file:///D:/Code/Brightwind/src/Logger/ConsoleLogger.ts) [DEBUG] 28:55.346 Hub - Dispatching to auth with Object { event: "signUp_failure", data: {…}, message: "karimfirefox1234@gmail.com failed to signup" } [ConsoleLogger.ts:99](file:///D:/Code/Brightwind/src/Logger/ConsoleLogger.ts) [DEBUG] 28:55.346 AnalyticsClass - on hub capsule auth Object { event: "signUp_failure", data: {…}, message: "karimfirefox1234@gmail.com failed to signup" } [ConsoleLogger.ts:99](file:///D:/Code/Brightwind/src/Logger/ConsoleLogger.ts) XHRPOSThttps://cognito-idp.eu-west-1.amazonaws.com/ [HTTP/2 400 Bad Request 87ms] [DEBUG] 28:55.418 Hub - Dispatching to auth with Object { event: "signUp_failure", data: {…}, message: "karimfirefox1234@gmail.com failed to signup" } [ConsoleLogger.ts:99](file:///D:/Code/Brightwind/src/Logger/ConsoleLogger.ts) [DEBUG] 28:55.418 Hub - Dispatching to auth with Object { event: "signUp_failure", data: {…}, message: "karimfirefox1234@gmail.com failed to signup" } [ConsoleLogger.ts:99](file:///D:/Code/Brightwind/src/Logger/ConsoleLogger.ts) [DEBUG] 28:55.418 AnalyticsClass - on hub capsule auth Object { event: "signUp_failure", data: {…}, message: "karimfirefox1234@gmail.com failed to signup" } ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

chrisbonifacio commented 2 years ago

Hi @karimtamerBW 👋 thanks for raising this issue. I noticed you are using a scoped amplify package (@aws-amplify/storage) and the global package (aws-amplify). Could you try upgrading both packages by running this command from your terminal?

npx npm-check-updates -i '/@?aws-amplify/' && npm update

If this doesn't work, please share how you're configuring Amplify in your project via Amplify.configure. You can also add this line to your index.js file to enable logging from the Amplify instance and it might help with debugging.

Amplify.Logger.LOG_LEVEL = "DEBUG"

karimtamerBW commented 2 years ago

Hey @chrisbonifacio, I apologize for the late reply. I updated my description for you to check the Amplify Config and the output logs.

I also tried upgrading the packages, but the issue still persists.

shwetajoshi601 commented 2 years ago

Hi @chrisbonifacio, Any more information on this issue?

tannerabread commented 2 years ago

:wave: @karimtamerBW, @shwetajoshi601 can you share your latest package.json?

karimtamerBW commented 2 years ago

Hello @tannerabread, thank you for your response.

{ "name": "frontend", "version": "0.1.0", "private": true, "dependencies": { "@aws-amplify/storage": "^3.4.4", "@emotion/react": "^11.6.0", "@emotion/styled": "^11.6.0", "@mui/icons-material": "^5.1.0", "@mui/lab": "^5.0.0-alpha.54", "@mui/material": "^5.1.0", "@mui/styles": "^5.1.0", "@mui/x-data-grid-pro": "^5.0.1", "@testing-library/jest-dom": "^5.11.0", "@testing-library/react": "^10.4.3", "@types/google-map-react": "^2.1.0", "@types/jest": "^24.0.0", "@types/lodash": "^4.14.165", "@types/node": "^12.0.0", "@types/react": "^17.0.34", "@types/react-dom": "^17.0.11", "@types/react-plotly.js": "^2.2.4", "@types/react-router-dom": "^5.1.5", "apexcharts": "^3.24.0", "aws-amplify": "^3.4.3", "axios": "^0.21.0", "clsx": "^1.1.1", "formik": "^2.2.9", "formik-mui": "^4.0.0-alpha.3", "formik-mui-lab": "^1.0.0-alpha.3", "google-map-react": "^2.1.9", "js-file-download": "^0.4.12", "lodash": "^4.17.21", "plotly.js": "^1.54.6", "react": "^17.0.2", "react-apexcharts": "^1.3.7", "react-dom": "^17.0.2", "react-dropzone": "^11.0.1", "react-html-parser": "^2.0.2", "react-json-view": "^1.20.5", "react-material-ui-carousel": "^3.0.4", "react-mui-dropzone": "^4.0.5", "react-plotly.js": "^2.4.0", "react-router-dom": "^5.2.0", "react-scripts": "4.0.3", "typescript": "^3.8.3", "uuid": "^3.4.0", "yup": "^0.32.11" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "coverage": "npm test -- --coverage --watchAll=false", "eject": "react-scripts eject", "lint": "eslint --ext .js,.jsx,.ts,.tsx src --color", "format": "prettier --write src/*/.{ts,tsx,scss,css,json}", "isready": "npm run format && npm run lint && npm run build" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "devDependencies": { "@sheerun/mutationobserver-shim": "^0.3.3", "@testing-library/user-event": "^14.4.1", "@types/react-html-parser": "^2.0.2", "@typescript-eslint/eslint-plugin": "4.33.0", "@typescript-eslint/parser": "4.33.0", "babel-eslint": "10.1.0", "cypress": "^9.1.0", "eslint-config-airbnb": "^19.0.1", "eslint-config-prettier": "8.3.0", "eslint-config-react-app": "6.0.0", "eslint-import-resolver-typescript": "2.5.0", "eslint-loader": "4.0.2", "eslint-plugin-flowtype": "5.10.0", "eslint-plugin-import": "2.25.3", "eslint-plugin-jsx-a11y": "6.5.1", "eslint-plugin-prettier": "4.0.0", "eslint-plugin-react": "7.27.1", "eslint-plugin-react-hooks": "4.3.0", "jest-canvas-mock": "^2.4.0", "prettier": "2.4.1", "prettier-eslint": "13.0.0", "prettier-eslint-cli": "5.0.1" }, "jest": { "resetMocks": true, "collectCoverageFrom": [ "src/*/.{ts,tsx,js,jsx}" ], "coveragePathIgnorePatterns": [ "src/components/LandingPage" ], "coverageThreshold": { "global": { "statements": 100, "branches": 50, "functions": 100, "lines": 100 } } } }

tannerabread commented 2 years ago

@karimtamerBW I see that you're still using v3 of amplify, is there a particular reason for that? It might help to delete your node_modules folder and reinstall with the latest v4 of amplify, if possible.

Also you should be able to get rid of the scoped @aws-amplify/storage package which could be causing issues with multiple instances of amplify

karimtamerBW commented 2 years ago

@tannerabread I did update to v4 and removed the @aws-amplify/storage but the issue still persists.

Here is how the dependencies look like now

"dependencies": {
    "@emotion/react": "^11.6.0",
    "@emotion/styled": "^11.6.0",
    "@mui/icons-material": "^5.1.0",
    "@mui/lab": "^5.0.0-alpha.54",
    "@mui/material": "^5.1.0",
    "@mui/styles": "^5.1.0",
    "@mui/x-data-grid-pro": "^5.0.1",
    "@testing-library/jest-dom": "^5.11.0",
    "@testing-library/react": "^10.4.3",
    "@types/google-map-react": "^2.1.0",
    "@types/jest": "^24.0.0",
    "@types/lodash": "^4.14.165",
    "@types/node": "^12.0.0",
    "@types/react": "^17.0.34",
    "@types/react-dom": "^17.0.11",
    "@types/react-plotly.js": "^2.2.4",
    "@types/react-router-dom": "^5.1.5",
    "apexcharts": "^3.24.0",
    "aws-amplify": "^4.3.39",
    "axios": "^0.21.0",
    "clsx": "^1.1.1",
    "formik": "^2.2.9",
    "formik-mui": "^4.0.0-alpha.3",
    "formik-mui-lab": "^1.0.0-alpha.3",
    "google-map-react": "^2.1.9",
    "js-file-download": "^0.4.12",
    "lodash": "^4.17.21",
    "plotly.js": "^1.54.6",
    "react": "^17.0.2",
    "react-apexcharts": "^1.3.7",
    "react-dom": "^17.0.2",
    "react-dropzone": "^11.0.1",
    "react-html-parser": "^2.0.2",
    "react-json-view": "^1.20.5",
    "react-material-ui-carousel": "^3.0.4",
    "react-mui-dropzone": "^4.0.5",
    "react-plotly.js": "^2.4.0",
    "react-router-dom": "^5.2.0",
    "react-scripts": "4.0.3",
    "typescript": "^3.8.3",
    "uuid": "^3.4.0",
    "yup": "^0.32.11"
  }
tannerabread commented 2 years ago

hi @karimtamerBW Sorry for the delayed response, I am attempting to reproduce this now but have a few questions.

I was curious about image this function when you are already adding the custom_header directly to your config? I'm a little confused on where/how you are using that function in the screenshot.

I'm also curious what the variable urls.confirmCreateAccount points to and if you created this flow for the Auth.signUp call or if you found that in the docs somewhere? I've never seen a call to that function followed by a history.push so it might be something there. This is the usual flow for calling Auth methods manually If you can explain the variable and how that's supposed to be used we might be able to find an error or I might be able to reproduce this

karimtamerBW commented 2 years ago

Hi @tannerabread

Thank you so much for your response.

The custom header is just an async function to get the Authorization header for API requests that are made through the application. It is an async function because Auth.currentSession() is an async function.

This has got nothing to do with SignUp, API requests are made after the user has been successfully authenticated through SignIn().

Our APIs are authenticated with Cognito and that is just specifying the configuration for APIs.

Following is the Amplify Config.

const commonEndpointConfig = {
  region: config.region,
  custom_header: async () => {
    const session = await Auth.currentSession();
    return {
      Authorization: get(session, 'idToken.jwtToken'),
    };
  },
};

const amplifyConfig = {
  API: {
    endpoints: [
      {
        name: apiName,
        endpoint: apiServiceEndpoint,
        ...commonEndpointConfig,
      },
    ],
  },
  Auth: {
    mandatorySignIn: true,
    ...authConfig,
  },
  Storage: {
    AWSS3: {
      bucket: config.measurementLocationsDocumentsBucket,
      region: authConfig.region,
      identityPoolId: config.identityPoolId,
    },
  },
};

In our index.tsx, this amplifyConfig is used as follows.

import Amplify from 'aws-amplify';
import amplifyConfig from './amplifyConfig';

Amplify.configure(amplifyConfig);

We have created this flow using the Cognito documentation. The history.push() is very commonly used in react for routing. We send a verification code via email after the user hits Sign Up and the user is required to enter this code to complete the process. It just navigates to a url to the page that has a form for the verification code and nothing else.

As mentioned earlier, this flow works perfectly on Chrome and Edge. However, on Firefox, there seem to be duplicate sign up requests causing an error.

Please let me know if you need any further information.

Thank you in advance.

tannerabread commented 1 year ago

hi @karimtamerBW I am still trying to repro but were the following lines of your Auth config found in documentation somewhere?

"measurementLocationsDocumentsBucket": <measurementLocationsDocumentsBucket>,
"loggerFilesBucket": <loggerFilesBucket>

I don't see those as options for the Auth config here.

I'm being specific about what is allowed because multiple requests sounds like it could be a config issue

karimtamerBW commented 1 year ago

Hey @tannerabread As suggested, I removed those lines from the configs, but the issue still persists.

tannerabread commented 1 year ago

Hi @karimtamerBW I haven't been able to reproduce this issue, I've so far only added the signup functionality to my MVP app but that was where you were pointing out the main issue is. I don't think we have yet mentioned but which version of firefox are you using? At the time of this posting I was on Firefox 102.4.0esr (64-bit)

Just to verify that my app was sending proper responses, I manually tried to sign up with the same email twice and got the 400 error with "An account with the given email already exists". I'm not seeing multiple requests though if I click the button once.

I have set up a repo with my sample app, maybe you can check to see if I'm doing anything glaringly different from your app that might be missing this bug.

Also, just to verify, the error was showing when you were clicking the signIn button on your app and not when you return back to it to verify?

karimtamerBW commented 1 year ago

Hey @tannerabread, I apologize for the late reply again.

This issue was faced on different versions of Firefox, but the one I'm currently using is 107.0.1 (64-bit). And yes, the issue was faced when the request was sent, not on the return back.

I also took a look at your sample code, and it indeed doesn't have any glaring difference to our implementation.

tannerabread commented 1 year ago

@karimtamerBW are you still running into the issue?

I'm unsure on how to reproduce your issue with everything we have discussed so far. Is it possible for you to set up a sample repo that reproduces this issue?

tannerabread commented 1 year ago

Hi @karimtamerBW, I'm not sure what changed but I was able to reproduce this with the same repo I had been working with before. Your screenshots from before have gone bad but can you confirm that what I see here is what you were also experiencing?

I deleted my test email address to register with, then went through the normal sign-up flow

Here is the screenshot of the failed request image

Along with the successful one image

karimtamerBW commented 1 year ago

Hello @tannerabread

Yes! That is exactly the issue faced.

Thank you so much for your follow up.

tannerabread commented 1 year ago

@karimtamerBW Glad that I was finally able to reproduce it! It was really odd that it worked without me changing anything about the sample repo I had supplied earlier. Someone else is going to look deeper into this to try to find the cause.

Just curious, how often do you experience this behavior?

karimtamerBW commented 1 year ago

@tannerabread Basically every time a Cognito request for authentication is made on Firefox.

shwetajoshi601 commented 1 year ago

Hi @helgabalashova! Has there been any progress on this issue? It was raised In August last year. Please let us know if you need more information.

The issue probably still persists, and @tannerabread was able to reproduce it too.