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
相关产品推荐
相关产品推荐

