Amplify-js: double POST to cognito /token endpoint (localhost development server only)

Created on 9 Dec 2020  路  4Comments  路  Source: aws-amplify/amplify-js

Describe the bug
Calls to auth.<region>.amazoncognito.com/oauth2/token intermittently fail with 400
Underlying cause appears to be double POST request

To Reproduce
Steps to reproduce the behavior:

  1. In browser, click "Sign in with AWS"
  2. Click the button for the identity provider
  3. Provide username & password if prompted, and click Sign In.
  4. Repeat 1-3 several times, observe multiple calls in network monitor and occasionally sign-in will work, other times it will fail with 400.

Expected behavior
Consistently successful sign-in experience

Code Snippet
Please provide a code snippet or a link to sample code of the issue you are experiencing to help us reproduce the issue. (Be sure to remove any sensitive data)

```import logo from './logo.svg';
import './App.css';
import '@aws-amplify/ui/dist/style.css';
import Amplify from "aws-amplify";
import awsExports from "./aws-exports";
import { withAuthenticator, AmplifySignOut } from '@aws-amplify/ui-react'

Amplify.configure(awsExports);

function App() {
return (



logo


Edit src/App.js and save to reload.


className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React




);
}

export default withAuthenticator(App)


**Screenshots**
Frequently both POST requests fail:
![](https://i.stack.imgur.com/RKUfG.png)

Occasionally one of them succeeds:
![](https://i.stack.imgur.com/MCtYO.png)

Browser 'issue' pane reports:
![image](https://user-images.githubusercontent.com/19296125/101555069-dc09de80-3985-11eb-910f-2f5ee6012308.png)
![](https://i.stack.imgur.com/CjsHQ.png)

Typically after a 400 error the user's email_verified status in the pool is reverted to `false` and a successful sign-in is met with a prompt to verify email:
![](https://i.stack.imgur.com/cBEM2m.png)


If applicable, add screenshots to help explain your problem.

**What is Configured?**
If applicable, please provide what is configured for Amplify CLI:
* Which steps did you follow via Amplify CLI when configuring your resources.
![image](https://user-images.githubusercontent.com/19296125/101565591-5abd4680-399b-11eb-828a-a2e7511275c1.png)
Also manually edited Cognito user pool to add my company's Azure AD as an identity provider (SAML)
* Which resources do you have configured?
Only auth.
  * If applicable, please provide your `aws-exports` file:

const awsmobile = {
"aws_project_region": "us-east-1",
"aws_cognito_identity_pool_id": "us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"aws_cognito_region": "us-east-1",
"aws_user_pools_id": "us-east-1_xxxxxxxxx",
"aws_user_pools_web_client_id": "xxxxxxxxxxxxxxxxxxxxxxxx",
"oauth": {
"domain": "xxxxxxxxxxxxxxxxx-xxxxxxx-xxx.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"
};


* If applicable, provide more configuration data, for example for Amazon Cognito, run `aws cognito-idp describe-user-pool --user-pool-id us-west-2_xxxxxx` (Be sure to remove any sensitive data)
<details>
  <summary><strong>UserPool Config</strong></summary> 

{
"UserPool": {
"Id": "us-east-1_xxxxxxxx",
"Name": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"Policies": {
"PasswordPolicy": {
"MinimumLength": 8,
"RequireUppercase": false,
"RequireLowercase": false,
"RequireNumbers": false,
"RequireSymbols": false,
"TemporaryPasswordValidityDays": 7
}
},
"LambdaConfig": {},
"LastModifiedDate": 1607445938.3,
"CreationDate": 1607445938.3,
"SchemaAttributes": [
{
"Name": "sub",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": false,
"Required": true,
"StringAttributeConstraints": {
"MinLength": "1",
"MaxLength": "2048"
}
},
{
"Name": "name",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "given_name",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "family_name",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "middle_name",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "nickname",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "preferred_username",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "profile",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "picture",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "website",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "email",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": true,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "email_verified",
"AttributeDataType": "Boolean",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false
},
{
"Name": "gender",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "birthdate",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "10",
"MaxLength": "10"
}
},
{
"Name": "zoneinfo",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "locale",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "phone_number",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "phone_number_verified",
"AttributeDataType": "Boolean",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false
},
{
"Name": "address",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {
"MinLength": "0",
"MaxLength": "2048"
}
},
{
"Name": "updated_at",
"AttributeDataType": "Number",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"NumberAttributeConstraints": {
"MinValue": "0"
}
},
{
"Name": "identities",
"AttributeDataType": "String",
"DeveloperOnlyAttribute": false,
"Mutable": true,
"Required": false,
"StringAttributeConstraints": {}
}
],
"AutoVerifiedAttributes": [
"email"
],
"UsernameAttributes": [
"email"
],
"SmsVerificationMessage": "Your verification code is {####}",
"EmailVerificationMessage": "Your verification code is {####}",
"EmailVerificationSubject": "Your verification code",
"VerificationMessageTemplate": {
"SmsMessage": "Your verification code is {####}",
"EmailMessage": "Your verification code is {####}",
"EmailSubject": "Your verification code",
"DefaultEmailOption": "CONFIRM_WITH_CODE"
},
"MfaConfiguration": "OFF",
"EstimatedNumberOfUsers": 1,
"EmailConfiguration": {
"EmailSendingAccount": "COGNITO_DEFAULT"
},
"SmsConfiguration": {
"SnsCallerArn": "arn:aws:iam::xxxxxxxxxxxx:role/xxxxxxxxxxxxxxx-dev",
"ExternalId": "zoomlo6cbcfd0f_role_external_id"
},
"UserPoolTags": {},
"Domain": "xxxxxxxxxxxxxxxxx-xxxxxxx-dev",
"AdminCreateUserConfig": {
"AllowAdminCreateUserOnly": false,
"UnusedAccountValidityDays": 7
},
"Arn": "arn:aws:cognito-idp:us-east-1:xxxxxxxxxxxx:userpool/us-east-1_xxxxxxxxx"
}
}

</details>

<details>
  <summary><strong>Environment</strong></summary>

<!-- Please run the following command inside your project and copy/paste the output into the codeblock: -->

npx envinfo --system --binaries --browsers --npmPackages --npmGlobalPackages
npx: installed 1 in 0.8s

System:
OS: Linux 4.19 Ubuntu 18.04.5 LTS (Bionic Beaver)
CPU: (8) x64 Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
Memory: 16.82 GB / 18.67 GB
Container: Yes
Shell: 5.4.2 - /usr/bin/zsh
Binaries:
Node: 15.3.0 - ~/.nvm/versions/node/v15.3.0/bin/node
npm: 6.14.9 - ~/.nvm/versions/node/v15.3.0/bin/npm
npmPackages:
@aws-amplify/ui-react: ^0.2.31 => 0.2.31
@testing-library/jest-dom: ^5.11.6 => 5.11.6
@testing-library/react: ^11.2.2 => 11.2.2
@testing-library/user-event: ^12.5.0 => 12.5.0
aws-amplify: ^3.3.11 => 3.3.11
react: ^17.0.1 => 17.0.1
react-dom: ^17.0.1 => 17.0.1
react-scripts: 4.0.1 => 4.0.1
web-vitals: ^0.2.4 => 0.2.4
npmGlobalPackages:
@aws-amplify/cli: 4.37.1
npm: 6.14.9
```

Smartphone (please complete the following information):

  • Device: Desktop Workstation
  • OS: Windows 10
  • Browser: Chrome
  • Version: 87.0.4280.88 (Official Build) (64-bit)]

Additional context
Add any other context about the problem here.

_You can turn on the debug mode to provide more info for us by setting window.LOG_LEVEL = 'DEBUG'; in your app._
Happy to provide log level but lots of scrubbing needed to protect info so only want to do so if deemed necessary.

Amplify UI Components Auth OAuth bug

Most helpful comment

I've been looking into this error quite a bit today, but it seems more complex than expected.

tldr; there's a development-only issue with including @aws-amplify/ui-components (via @aws-amplify/ui-react) that's causing Auth to handle token negotiation twice that wasn't present in aws-amplify-react.

Why?

I believe the difference between the two comes down to:

https://github.com/aws-amplify/amplify-js/blob/84472392551c8c9b1c81c4c76de49752d9d4a653/packages/amplify-ui-components/package.json#L37-L42

vs.

https://github.com/aws-amplify/amplify-js/blob/84472392551c8c9b1c81c4c76de49752d9d4a653/packages/aws-amplify-react/package.json#L113-L121

In development, React is including duplicate versions of Amplify specified by dependencies. In production, these are de-duped. aws-amplify-react _correctly uses peerDependencies_, avoiding this issue entirely.

What can we do to fix it?

The Amplify team can move dependencies to peerDependencies, like aws-amplify-react.

How'd you come to this conclusion anyway?

I'm doing a couple of things:

  1. First, hitting http://localhost:3000/?code=test with Create React App
  2. Then, logging how often we call OAuth._handleCodeFlow to handle the ?code=test part

    Notice this happens _once_.

  3. Then, log how many times we call fetch and if fetch === window.fetch (true)

    Again, notice this happens _once_.

  4. Even with an invalid code, **for some reason there are two POST network calls, despite only a single fetch and singleOAuth._handleCodeFlow call!

Screen Shot 2021-01-21 at 2 05 53 PM

Screen Shot 2021-01-21 at 2 18 49 PM

But this makes zero sense.

So, I started isolating App.tsx to see what was causing multiple POST /token calls:

  1. Amplify.configure is fine
  2. Auth.currentAuthenticatedUser is fine
  3. <AmplifyAuthenticator> does the double-POST!
  4. <AmplifySignOut> does the double-POST!
  5. Wrapping the app withAuthenticator also does the double-POST!
  6. withAuthenticator from aws-amplify-react DOES NOT do the double-POST!

All 4 comments

I know in other similar issues the cause of the double POST to /token has been calling Amplify.configure() twice. I've verified my code calls this only once in index.js

I've confirmed this issue disappears if I publish to amplify and use the public endpoint (with callback URLs changed appropriately). The issue appears to be limited to the local development server.

NOTE I tried removing StrictMode as I've read it can cause components to double-render on local dev servers. This made no difference (my component also still double-renders despite removing it)

+1 Well documented. We noticed this issue as well and spent a lot of time trying to debug it. Only solution we could find is to run a production build and you'll see the errors disappear. This is not ideal at all when working in development mode for the login to fail randomly with this error.

I've been looking into this error quite a bit today, but it seems more complex than expected.

tldr; there's a development-only issue with including @aws-amplify/ui-components (via @aws-amplify/ui-react) that's causing Auth to handle token negotiation twice that wasn't present in aws-amplify-react.

Why?

I believe the difference between the two comes down to:

https://github.com/aws-amplify/amplify-js/blob/84472392551c8c9b1c81c4c76de49752d9d4a653/packages/amplify-ui-components/package.json#L37-L42

vs.

https://github.com/aws-amplify/amplify-js/blob/84472392551c8c9b1c81c4c76de49752d9d4a653/packages/aws-amplify-react/package.json#L113-L121

In development, React is including duplicate versions of Amplify specified by dependencies. In production, these are de-duped. aws-amplify-react _correctly uses peerDependencies_, avoiding this issue entirely.

What can we do to fix it?

The Amplify team can move dependencies to peerDependencies, like aws-amplify-react.

How'd you come to this conclusion anyway?

I'm doing a couple of things:

  1. First, hitting http://localhost:3000/?code=test with Create React App
  2. Then, logging how often we call OAuth._handleCodeFlow to handle the ?code=test part

    Notice this happens _once_.

  3. Then, log how many times we call fetch and if fetch === window.fetch (true)

    Again, notice this happens _once_.

  4. Even with an invalid code, **for some reason there are two POST network calls, despite only a single fetch and singleOAuth._handleCodeFlow call!

Screen Shot 2021-01-21 at 2 05 53 PM

Screen Shot 2021-01-21 at 2 18 49 PM

But this makes zero sense.

So, I started isolating App.tsx to see what was causing multiple POST /token calls:

  1. Amplify.configure is fine
  2. Auth.currentAuthenticatedUser is fine
  3. <AmplifyAuthenticator> does the double-POST!
  4. <AmplifySignOut> does the double-POST!
  5. Wrapping the app withAuthenticator also does the double-POST!
  6. withAuthenticator from aws-amplify-react DOES NOT do the double-POST!
Was this page helpful?
0 / 5 - 0 ratings

Related issues

guanzo picture guanzo  路  3Comments

callmekatootie picture callmekatootie  路  3Comments

simon998yang picture simon998yang  路  3Comments

benevolentprof picture benevolentprof  路  3Comments

karlmosenbacher picture karlmosenbacher  路  3Comments