You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Amplify使用SAML登录成功仍报invalid_grant错误的原因与解决

问题原因

  • 核心是Amplify Auth的回调处理时序和你调用currentAuthenticatedUser的时机不匹配:你当前在App组件挂载时直接触发用户信息查询,此时SAML登录回调返回的授权码还没被Amplify完成兑换token的流程,提前调用会导致授权码被异常消费/未就绪,触发invalid_grant错误。刷新页面后token已经写入本地存储,无需走授权码兑换流程,所以直接读取正常。
  • 偶发多次登录才能成功的问题,通常是上一次登录的授权码残留未清理、SAML断言属性和Cognito用户池属性映射不匹配,或者Cognito应用客户端的授权码有效期设置过短导致。

修复方案

1. 基于Auth事件监听的正式修复

不要在根组件挂载时直接查询用户信息,改为监听Amplify Hub模块的auth事件,等登录流程完全完成后再触发用户信息查询,同时显式启用PKCE适配授权码登录模式:

修改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';

// 显式开启PKCE,适配授权码模式的SAML登录
Amplify.configure({
  ...awsconfig,
  oauth: {
    ...awsconfig.oauth,
    pkce: true
  }
})

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

reportWebVitals();

修改App.js逻辑

import { Auth, Hub } from 'aws-amplify';

// ...其他导入保持不变

useEffect(() => {
  // 监听Auth生命周期事件
  const handleAuthEvent = (eventData) => {
    const { payload } = eventData;
    if (payload.event === 'signIn') {
      // 登录流程完全完成后再获取用户信息
      checkUser();
    }
  };

  Hub.listen('auth', handleAuthEvent);

  // 初始化时仅检查本地已存在的登录态,异常时不主动触发兑换流程
  Auth.currentAuthenticatedUser({
    bypassCache: false
  }).then(user => {
    console.log('已登录用户:', user);
  }).catch(() => {
    // 未登录时忽略错误,等待用户主动触发登录
  });

  return () => Hub.remove('auth', handleAuthEvent);
}, []);

async function checkUser() {
  try {
    const cognitoUser = await Auth.currentAuthenticatedUser();
    console.log('user info: ', cognitoUser);
    // 后续处理用户信息的逻辑保持不变
  } catch (err) {
    console.error('获取用户信息失败:', err);
  }
}

// ...其余代码保持不变

2. 快速规避方案(临时使用)

如果需要快速上线,可以通过异常捕获+单次刷新的方式规避问题,避免用户手动刷新:
在checkUser的异常捕获分支中加入以下逻辑:

async function checkUser() {
  try {
    const cognitoUser = await Auth.currentAuthenticatedUser();
    console.log('user info: ', cognitoUser);
    sessionStorage.removeItem('loginRefreshed');
  } catch (err) {
    if (err.message === 'invalid_grant' && !sessionStorage.getItem('loginRefreshed')) {
      sessionStorage.setItem('loginRefreshed', 'true');
      window.location.reload();
    }
  }
}

3. 额外检查项

如果仍存在多次登录才能成功的问题,检查以下配置:

  • Cognito用户池的属性映射配置,确保Azure AD返回的SAML断言中的必填属性(如email、name等)和Cognito用户池属性一一对应,无缺失
  • Cognito应用客户端的授权码有效期设置不低于5分钟,避免授权码在兑换前过期
  • 重定向URI配置完全匹配,无尾部斜杠、大小写不一致的问题

内容的提问来源于stack exchange,提问作者Lance

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 17:45:00