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

React集成AWS Cognito与Google授权:授权码换令牌失败

React中AWS Cognito+Google登录:授权码换令牌报错问题

我在React项目中基于AWS Cognito实现Google登录功能,已完成授权码返回至redirect_uri的步骤,地址栏能看到授权码(格式示例:http://localhost:3000/?code=e3090fba-d39c-4c8d-aaf9-4e82ebafcc70&state=BBCxKTIPx4QLwD17kOAhl0OyKo3f7g7O)。当前尝试向https://<my_domain>.amazoncognito.com/oauth2/token发送POST请求换取access token和id token,但通过首页useEffect编写的代码执行时报错。Cognito的OAuth授权类型已设置为Authorization code grant。

AWS Amplify配置代码

Amplify.configure({
    Auth: {
        region: '*******',
        userPoolId: '***************',
        userPoolWebClientId: '**************',
        oauth : {
            domain: '<domain-name>.amazoncognito.com',
            redirectSignIn: 'http://localhost:3000',
            redirectSignOut: 'http://localhost:3000',
            scope : ['email', 'openid', 'profile', 'phone', 'aws.cognito.signin.user.admin'],
            responseType: 'code'
        }
    }
})

令牌请求代码

useEffect(() => {
    const exchangeCodeForTokens = async () => {
      try {
        const urlParams = new URLSearchParams(window.location.search);

        if (urlParams.has('code')) {
          const dcode = urlParams.get('code');
          const code = String(dcode)
          console.log(code)
        const tokenEndpoint = 'https://<my-domain>.amazoncognito.com/oauth2/token';
        const clientId = <my-cognito-client-id>;
        const redirectUri = 'http://localhost:3000';

        const bodyParams = new URLSearchParams();
        bodyParams.append('grant_type', 'authorization_code');
        bodyParams.append('client_id', clientId);
        bodyParams.append('code', code);
        bodyParams.append('redirect_uri', redirectUri);

        const response = await fetch(tokenEndpoint, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
          },
          body: bodyParams.toString(),
        });
        
        console.log(response)
        const data = await response.json();
        const accessToken = data.access_token;
        const idToken = data.id_token;
        const refreshToken = data.refresh_token;

        console.log(data,accessToken, idToken, refreshToken)

        console.log('Token exchange successful');
      }
      } catch (error) {
        console.error(error);
      }
    };

    exchangeCodeForTokens();
  }, []);

常见报错排查与解决

  • 客户端凭证问题:如果Cognito用户池客户端设置了客户端密钥,POST请求需添加Authorization头,值为Base64编码的client_id:client_secret。若未设置密钥,确认客户端配置中允许的OAuth流勾选了Authorization code grant,且允许的OAuth范围包含请求里的所有scope。
  • redirect_uri不匹配:确保请求中的redirect_uri与Cognito客户端配置的回调URL完全一致,包括协议(http/https)、端口、路径,不能有任何差异。
  • 授权码失效:Cognito授权码有效期仅10分钟且只能使用一次,重复使用或超时都会报错,需重新发起授权流程。
  • CORS配置问题:检查Cognito用户池域名的CORS设置,是否允许http://localhost:3000发起POST请求。更简便的方式是使用Amplify内置方法自动处理令牌交换,避免手动处理CORS:
    useEffect(() => {
      const handleAuthCallback = async () => {
        try {
          const urlParams = new URLSearchParams(window.location.search);
          if (urlParams.has('code')) {
            await Auth.federatedSignIn({ provider: 'Google' });
            const user = await Auth.currentAuthenticatedUser();
            console.log(user);
          }
        } catch (error) {
          console.error(error);
        }
      };
      handleAuthCallback();
    }, []);
    
  • 请求格式错误:确认bodyParams的参数名拼写完全正确(比如grant_type必须是authorization_code),同时替换代码中占位符<my-cognito-client-id>为实际的客户端ID。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:42:43