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

OAuth - Error handling auth response. Error: invalid_grant for Federated Google Login after deleting account #6172

Closed
Jun711 opened this issue Jun 26, 2020 · 5 comments
Assignees
Labels
not-reproducible Not able to reproduce the issue OAuth For issues related to OAuth

Comments

@Jun711
Copy link

Jun711 commented Jun 26, 2020

Describe the bug
A clear and concise description of what the bug is.
After deleting a google EXTERNAL_PROVIDER account, within the next hour, if I create a Cognito account using the same gmail and link them, I cannot use Auth.federatedSignIn({provider: 'Google'}) to log in again and the error is Error: invalid_grant.

It would work fine without first deleting a google EXTERNAL_PROVIDER account.
Note that I am able to login with Google and link account in backend. This error only happens when a google EXTERNAL_PROVIDER account is deleted and recreated within an hour.

It seems to be caused by token not reset in Cognito.

https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html

invalid_grant
Refresh token has been revoked.

Authorization code has been consumed already or does not exist.

I have checked #3185 Mine doesn't have 2 token requests
I have checked #6041 but steps to reproduce are different as mine has deleting account step.
I have checked #5829 It seems to be the same issue as #3185
It could be related to #4720


To Reproduce
Steps to reproduce the behavior:

  1. login with google (an account with EXTERNAL_PROVIDER status would appear in the user pool).
    Note that there is no Cognito account with the same gmail in the user pool.

  2. delete this EXTERNAL_PROVIDER account using the following code

const user = await Auth.currentAuthenticatedUser();
user.deleteUser((error, data) => {
    if (error) {
      throw error;
    }
  });
  1. sign up for a Cognito account using the same gmail (an account with UNCONFIRMED status would appear in the user pool)

  2. login with google again using the same gmail (step 1). This time EXTERNAL_PROVIDER account would be linked with the cognito account that has the same email.

  3. Token endpoint https://my-domain/oauth2/token would fail with OAuth - Error handling auth response. Error: invalid_grant error.

Screen Shot 2020-06-25 at 5 32 33 PM

  1. local eventing system Hub would receive these events

Screen Shot 2020-06-25 at 5 36 03 PM

event:  "signIn_failure"
data:  Error: invalid_grant at e.<anonymous>
message: "The OAuth response flow failed"
event:  "cognitoHostedUI_failure"
data: Error: invalid_grant at e.<anonymous>
message: "A failure occurred when returning to the Cognito Hosted UI"
event:  "customState_failure"
data: Error: invalid_grant at e.<anonymous>
message: "A failure occurred when returning state"

Expected behavior

1 Token for Login with Google is reset after deleting an EXTERNAL_PROVIDER account.
2 Login with Google can login successfully after deleting an EXTERNAL_PROVIDER account.

Code Snippet

login with Google

Auth.federatedSignIn({provider: 'Google'})

delete account

const user = await Auth.currentAuthenticatedUser();
user.deleteUser((error, data) => {
    if (error) {
      throw error;
    }
  });

What is Configured?
I was using "aws-amplify": "^3.0.9" when I first tested. I have updated it to 3.0.18 but I got the same error.

manual configuration:

{
  Auth: {
        identityPoolId: 'XX-XXXX-X:XXXXXXXX-XXXX-1234-abcd-1234567890ab',
        userPoolId:  'XX-XXXX-X_abcd1234',
        userPoolWebClientId: 'a1b2c3d4e5f6g7h8i9j0k1l2m3',
        region:'XX-XXXX-X',
        identityPoolRegion: 'XX-XXXX-X',
        oauth: {
          domain: domain,
          clientID:  'a1b2c3d4e5f6g7h8i9j0k1l2m3',
          scope: ['email', 'profile', 'openid',  'aws.cognito.signin.user.admin'],
          redirectSignIn: redirectSignInLink,
          redirectSignOut: redirectSignOutLink,
          responseType: 'code'
        }
      }     
}
Environment
npx envinfo --system --binaries --browsers --npmPackages --npmGlobalPackages

"aws-amplify": "^3.0.18"
"@aws-amplify/auth": "^3.2.13"

You can turn on the debug mode to provide more info for us by setting window.LOG_LEVEL = 'DEBUG'; in your app.

@Jun711 Jun711 added the to-be-reproduced Used in order for Amplify to reproduce said issue label Jun 26, 2020
@elorzafe elorzafe added the OAuth For issues related to OAuth label Jun 26, 2020
@shide1989
Copy link

Having the same error with "@aws-amplify/auth": "^3.2.4", but with an External OIDC Provider

@batmanwannabe
Copy link

Facing the same error with "aws-amplify": "3.0.19" and Azure AD SAML authentication

@elorzafe
Copy link
Contributor

@Jun711 I follow the same steps as you mention and I couldnt reproduce when I was deleting the linked account on Cognito console.

I used this Pre SignUp trigger code for linking the account

var CognitoIdentityServiceProvider = require('aws-sdk/clients/cognitoidentityserviceprovider');

const cognitoIdp = new CognitoIdentityServiceProvider()
const getUserByEmail = async (userPoolId, email) => {
 const params = {
   UserPoolId: userPoolId,
   Filter: `email = "${email}"`
 }
 return cognitoIdp.listUsers(params).promise()
}

const linkProviderToUser = async (username, userPoolId, providerName, providerUserId) => {
 const params = {
   DestinationUser: {
     ProviderAttributeValue: username,
     ProviderName: 'Cognito'
   },
   SourceUser: {
     ProviderAttributeName: 'Cognito_Subject',
     ProviderAttributeValue: providerUserId,
     ProviderName: providerName
   },
   UserPoolId: userPoolId
 }

 const result = await (new Promise((resolve, reject) => {
   cognitoIdp.adminLinkProviderForUser(params, (err, data) => {
     if (err) {
       reject(err)
       return
     }
     resolve(data)
   })
 }))

 return result
}

exports.handler = async (event, context, callback) => {
 if (event.triggerSource === 'PreSignUp_ExternalProvider') {
   const userRs = await getUserByEmail(event.userPoolId, event.request.userAttributes.email)
   if (userRs && userRs.Users.length > 0) {
     const [ providerName, providerUserId ] = event.userName.split('_') // event userName example: "Facebook_12324325436"
     await linkProviderToUser(userRs.Users[0].Username, event.userPoolId, providerName, providerUserId)
   } else {
     console.log('user not found, skip.')
   }

 }
 return callback(null, event)
}

Can you share the steps you are doing for linking the account and deleting the linked account?

@elorzafe elorzafe added not-reproducible Not able to reproduce the issue pending-close-response-required and removed to-be-reproduced Used in order for Amplify to reproduce said issue labels Sep 24, 2020
@stale
Copy link

stale bot commented Oct 4, 2020

This issue has been automatically closed because of inactivity. Please open a new issue if are still encountering problems.

@stale stale bot closed this as completed Oct 4, 2020
@github-actions
Copy link

github-actions bot commented Oct 4, 2021

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
not-reproducible Not able to reproduce the issue OAuth For issues related to OAuth
Projects
None yet
Development

No branches or pull requests

5 participants