为什么我使用 AWS Amplify 成功登录后仍出现 invalid_grant 错误?

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

我目前使用 AWS Amplify with SAML (Microsoft Azure AD) 作为联合身份提供商。我已经使用 amplify import auth 将这个现有的 Cognito 池导入到我的 create-react-app 项目中。但是,当我成功登录时(它重定向到我的主页),即使我正确登录,它也会显示此 invalid_grant 错误。然后,如果我刷新我的页面,错误就消失了,我可以看到我登录用户的 Cognito 信息已成功登录。

是什么导致“第一次”登录无法立即工作并出现错误?我检查了我的 aws-exports.js 文件,里面的配置应该都是正确的,因为我可以登录,只是登录后需要刷新页面。

此外,偶尔我会遇到这个问题,我需要登录 两次 或大约 3-4 次,因为第一次登录会导致此错误:

是否有任何方法可以覆盖此问题,例如在登录后在主页上自动刷新等或修复此问题?

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 应用客户端设置

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;

首次登录错误

刷新页面后,Cognito 用户信息显示为已登录

经过几天的 AWS 支持通过他们的支持中心进行故障排除后,不幸的是我仍然没有找到问题所在。

然而,经过今天的一些修补,我终于找到了解决这个问题的方法。

最初,当我使用 amplify import auth 导入用户池和身份池时,oauth 配置实际上一起导入并且位于 aws-exports.js.

基本上我所做的是删除 oauth 的配置,使其为空,在 aws-exports.js 中看起来像这样:"oauth": {}。然后,我复制相同的配置并将其粘贴到我的 index.js 中,并使用 Auth.configure 来配置 oauth。所以 index.js 中的最终结果如下所示:

Amplify.configure(awsconfig);

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

Auth.configure({
    oauth: oauth,
});

这就是我为我的项目解决这个问题的方法,仅供将来使用 amplify import authoauth 设置导入 aws-exports.js 文件时遇到相同问题的人参考还有。

这有点奇怪,因为如果 oauth 不打算与 Amplify.configure 一起使用,为什么 AWS 在使用 amplify import auth 时将它包含在 aws-exports.js 中?