Search code examples
reactjsamazon-web-servicesamazon-cognitocreate-react-appaws-amplify

Why there's invalid_grant error even though I successfully logged in with AWS Amplify?


I'm currently using AWS Amplify with SAML(Microsoft Azure AD) as the federated identity provider. I've used amplify import auth to import this existing Cognito pool into my create-react-app project. However when I logged in successfully (it redirects to my homepage), it shows this invalid_grant error even though I logged in correctly. Then if I refreshed my page, then the error is gone and I can see my logged in user's Cognito info as successfully logged in.

What is causing this "first time" log in not being able to work straightaway and has an error? I've checked my aws-exports.js file and the config inside should be all correct as I'm able to sign in, just that after signing in requires a page refresh.

Also, occasionally I would have this problem where I need to sign in twice or like 3-4 times, as the first sign in leads to this error: enter image description here

Is there any method to override this like doing an auto refresh at the homepage after signing in etc or fixing this?

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.scss';
import App from './App';
import reportWebVitals from './reportWebVitals';
import Amplify from 'aws-amplify';
import awsconfig from './aws-exports';

Amplify.configure(awsconfig)

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: 
reportWebVitals();

App.js

useEffect(() => {
    checkUser()
  }, [])

  async function checkUser() {
    try {
      const cognitoUser = await Auth.currentAuthenticatedUser();
      console.log('user info: ', cognitoUser)
  }

return (
    <AmplifyAuthenticator>
      <div className="App" slot="sign-in" style={{
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        height: '100vh',
        backgroundImage: `url(${Background})`,
        backgroundSize: 'cover',
        width: '100%'
      }}>
        <AmplifySignIn
          headerText="Welcome"
          slot="sign-in"
          hideSignUp
        ></AmplifySignIn>
      </div>
      <BrowserRouter>
        <Sidebar AmplifySignOut={AmplifySignOut} username={userName} />
        <Switch>
          <Route path='/' component={Home} exact />
          <Route path='/bulletinboard' component={BulletinBoard} exact />
          <Route path='/bulletinboard/create' component={AddBulletin} exact />
          <Route path='/bulletinboard/edit/:id' component={EditBulletin} exact />
          <Route path='/infohub' component={InfoHub} exact />sec
          <Route path='/infohub/folder' component={InfoHubCategory} exact />
          <Route path='/settings' component={Settings} exact />
          <Route component={NotFound} />
        </Switch>
      </BrowserRouter>
    </AmplifyAuthenticator>
  )

Cognito App Client settings enter image description here

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": "****",
    "aws_cognito_identity_pool_id": "****",
    "aws_cognito_region": "****",
    "aws_user_pools_id": "****",
    "aws_user_pools_web_client_id": "****",
    "oauth": {
        "domain": "****",
        "scope": [
            "aws.cognito.signin.user.admin",
            "email",
            "openid",
            "phone",
            "profile"
        ],
        "redirectSignIn": "****",
        "redirectSignOut": "****",
        "responseType": "code"
    },
    "federationTarget": "COGNITO_USER_POOLS",
    "aws_user_files_s3_bucket": "****",
    "aws_user_files_s3_bucket_region": "****"
};


export default awsmobile;

First time login error

enter image description here

After refreshing page, Cognito user info shows as logged in

enter image description here


Solution

  • After a few days of troubleshooting with AWS supports through their Support Centre, unfortunately I still haven't managed to find out the problem.

    However, after a little bit of tinkering today I've finally found the solution to this problem.

    Initially, when I used amplify import auth to import the User Pool & Identity Pool, the oauth configurations actually got imported together and is located inside aws-exports.js.

    Basically what I did was removing the oauth's configuration so that it is empty and it looks like this in aws-exports.js: "oauth": {}. Then, I copied the same configuration and pasted it in my index.js and used Auth.configure to configure the oauth. So final results in the index.js look like this:

    Amplify.configure(awsconfig);
    
    const oauth = {
        domain: '****',
        scope: [
            'aws.cognito.signin.user.admin',
            'email',
            'openid',
            'phone',
            'profile',
        ],
        redirectSignIn: '****',
        redirectSignOut: '****',
        responseType: 'code',
    };
    
    Auth.configure({
        oauth: oauth,
    });
    

    That's how I solve this issue for my project, just for future reference if anyone has the same problem when using amplify import auth and the oauth settings got imported in the aws-exports.js file as well.

    It's just a little weird because if the oauth is not meant to be used with Amplify.configure, why does AWS includes it inside aws-exports.js when using amplify import auth?