求助:React集成AWS Cognito谷歌社交登录(无托管UI、无Amplify)
React + AWS Cognito + 谷歌社交登录(无托管UI/Amplify)实现方案
前置准备
- 在谷歌云平台创建OAuth 2.0客户端,配置授权重定向URI为
https://{你的Cognito域名}.auth.{区域}.amazoncognito.com/oauth2/idpresponse - 在AWS Cognito用户池中添加谷歌作为身份提供商,填入谷歌客户端ID和客户端密钥
- 配置Cognito应用客户端,启用授权码流,并将前端回调URL(比如
http://localhost:3000/cognito-callback)加入允许列表
安装依赖
npm install @aws-sdk/client-cognito-identity-provider
代码实现
1. 谷歌登录按钮组件
import { useState } from 'react'; const GoogleLoginButton = () => { // 替换为你的实际配置 const COGNITO_DOMAIN = 'your-cognito-domain.auth.region.amazoncognito.com'; const CLIENT_ID = 'your-cognito-app-client-id'; const REDIRECT_URI = 'http://localhost:3000/cognito-callback'; const SCOPE = 'openid email profile'; const PROVIDER = 'Google'; const handleLogin = () => { // 构造Cognito授权跳转URL const authUrl = `${COGNITO_DOMAIN}/oauth2/authorize?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&scope=${SCOPE}&identity_provider=${PROVIDER}`; window.location.href = authUrl; }; return ( <button onClick={handleLogin} style={{ padding: '10px 20px', backgroundColor: '#4285F4', color: 'white', border: 'none', borderRadius: '4px', cursor: 'pointer', fontSize: '16px' }} > 用谷歌登录 </button> ); }; export default GoogleLoginButton;
2. 回调处理组件
import { useEffect, useState } from 'react'; import { CognitoIdentityProviderClient, InitiateAuthCommand } from '@aws-sdk/client-cognito-identity-provider'; const CognitoCallback = () => { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // 替换为你的实际配置 const COGNITO_CLIENT_ID = 'your-cognito-app-client-id'; const REDIRECT_URI = 'http://localhost:3000/cognito-callback'; const REGION = 'your-aws-region'; useEffect(() => { const exchangeCodeForTokens = async () => { try { // 从URL中提取授权码 const urlParams = new URLSearchParams(window.location.search); const authCode = urlParams.get('code'); if (!authCode) throw new Error('未获取到授权码'); // 初始化Cognito客户端 const cognitoClient = new CognitoIdentityProviderClient({ region: REGION }); // 发送授权码交换令牌请求 const command = new InitiateAuthCommand({ ClientId: COGNITO_CLIENT_ID, AuthFlow: 'AUTHORIZATION_CODE_AUTH', AuthParameters: { CODE: authCode, REDIRECT_URI: REDIRECT_URI } }); const authResult = await cognitoClient.send(command); // 存储令牌(生产环境建议用安全的存储方案,比如HttpOnly Cookie) localStorage.setItem('idToken', authResult.AuthenticationResult.IdToken); localStorage.setItem('accessToken', authResult.AuthenticationResult.AccessToken); localStorage.setItem('refreshToken', authResult.AuthenticationResult.RefreshToken); // 跳转至应用主页 window.location.href = '/'; } catch (err) { setError(err.message); } finally { setLoading(false); } }; exchangeCodeForTokens(); }, []); if (loading) return <div>正在处理登录,请稍候...</div>; if (error) return <div className="text-red-500">登录失败: {error}</div>; return <div>登录成功!正在跳转...</div>; }; export default CognitoCallback;
关键注意事项
- 生产环境不要硬编码敏感配置,使用React环境变量(比如
process.env.REACT_APP_COGNITO_DOMAIN) - 确保Cognito用户池的身份提供商配置中,谷歌的客户端ID/密钥正确
- 前端回调URL必须和Cognito应用客户端配置的允许列表完全一致
- 令牌存储建议使用HttpOnly Cookie而非localStorage,提升安全性
内容的提问来源于stack exchange,提问作者jacob
相关产品推荐
相关产品推荐

