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:
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 (
Edit src/App.js and save to reload.
export default withAuthenticator(App)
**Screenshots**
Frequently both POST requests fail:

Occasionally one of them succeeds:

Browser 'issue' pane reports:


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:

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.

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):
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.
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.
I believe the difference between the two comes down to:
vs.
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.
The Amplify team can move dependencies to peerDependencies, like aws-amplify-react.
I'm doing a couple of things:
http://localhost:3000/?code=test with Create React AppThen, logging how often we call OAuth._handleCodeFlow to handle the ?code=test part
Notice this happens _once_.
Then, log how many times we call fetch and if fetch === window.fetch (true)
Again, notice this happens _once_.
Even with an invalid code, **for some reason there are two POST network calls, despite only a single fetch and singleOAuth._handleCodeFlow call!
But this makes zero sense.
So, I started isolating App.tsx to see what was causing multiple POST /token calls:
Amplify.configure is fineAuth.currentAuthenticatedUser is fine<AmplifyAuthenticator> does the double-POST!<AmplifySignOut> does the double-POST!withAuthenticator also does the double-POST!withAuthenticator from aws-amplify-react DOES NOT do the double-POST!
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 causingAuthto handle token negotiation twice that wasn't present inaws-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 ofAmplifyspecified bydependencies. Inproduction, these are de-duped.aws-amplify-react_correctly usespeerDependencies_, avoiding this issue entirely.What can we do to fix it?
The Amplify team can move dependencies to
peerDependencies, likeaws-amplify-react.How'd you come to this conclusion anyway?
I'm doing a couple of things:
http://localhost:3000/?code=testwith Create React AppThen, logging how often we call
OAuth._handleCodeFlowto handle the?code=testpartNotice this happens _once_.
Then, log how many times we call
fetchand iffetch === window.fetch(true)Again, notice this happens _once_.
Even with an invalid code, **for some reason there are two
POSTnetwork calls, despite only a singlefetchand singleOAuth._handleCodeFlowcall!But this makes zero sense.
So, I started isolating
App.tsxto see what was causing multiplePOST /tokencalls:Amplify.configureis fineAuth.currentAuthenticatedUseris fine<AmplifyAuthenticator>does the double-POST!<AmplifySignOut>does the double-POST!withAuthenticatoralso does the double-POST!withAuthenticatorfromaws-amplify-reactDOES NOT do the double-POST!