在PHP中使用Amazon Cognito SDK集成谷歌认证(无需托管UI)
可以不借助托管UI,直接通过Cognito SDK实现谷歌认证
完全可以脱离Cognito托管UI,结合谷歌OAuth 2.0流程与Cognito SDK实现自定义表单中的谷歌登录,核心逻辑是让用户通过谷歌授权后,将谷歌返回的身份令牌传递给Cognito完成身份校验并生成Cognito自身的用户令牌。以下是具体实现步骤:
1. 配置Cognito用户池的谷歌身份提供商
- 登录AWS控制台,进入目标Cognito用户池,在「身份提供商」选项卡添加谷歌作为身份提供商
- 填入谷歌开发者平台创建的OAuth客户端ID、客户端密钥,设置授权范围(推荐
openid email profile) - 配置回调URL:指向你的PHP网站中处理谷歌授权回调的页面(例如
https://your-domain.com/google-callback.php)
2. 在自定义表单中添加谷歌登录按钮
按钮点击后引导用户跳转到谷歌授权页面,需构造包含必要参数的授权URL:
<?php session_start(); $googleClientId = '你的谷歌OAuth客户端ID'; $redirectUri = 'https://your-domain.com/google-callback.php'; // 生成随机state值防CSRF $state = bin2hex(random_bytes(16)); $_SESSION['google_oauth_state'] = $state; $authUrl = sprintf( 'https://accounts.google.com/o/oauth2/v2/auth?client_id=%s&redirect_uri=%s&response_type=code&scope=openid%%20email%%20profile&state=%s', $googleClientId, urlencode($redirectUri), $state ); ?> <a href="<?= $authUrl ?>" class="google-login-btn">使用谷歌登录</a>
3. 处理谷歌授权回调,获取ID令牌
在回调页面中验证CSRF状态,并用授权码换取谷歌的ID令牌:
<?php session_start(); if (!isset($_GET['code'], $_GET['state']) || $_GET['state'] !== $_SESSION['google_oauth_state']) { die('请求验证失败'); } unset($_SESSION['google_oauth_state']); $googleClientId = '你的谷歌OAuth客户端ID'; $googleClientSecret = '你的谷歌OAuth客户端密钥'; $redirectUri = 'https://your-domain.com/google-callback.php'; $code = $_GET['code']; // 向谷歌请求令牌 $tokenResponse = file_get_contents('https://oauth2.googleapis.com/token', false, stream_context_create([ 'http' => [ 'method' => 'POST', 'header' => 'Content-Type: application/x-www-form-urlencoded', 'content' => http_build_query([ 'code' => $code, 'client_id' => $googleClientId, 'client_secret' => $googleClientSecret, 'redirect_uri' => $redirectUri, 'grant_type' => 'authorization_code' ]) ] ])); $tokenData = json_decode($tokenResponse, true); if (!isset($tokenData['id_token'])) { die('获取谷歌令牌失败'); } $googleIdToken = $tokenData['id_token']; ?>
4. 调用Cognito SDK完成身份认证
使用AWS PHP SDK将谷歌ID令牌传递给Cognito,获取Cognito的用户令牌:
<?php require 'vendor/autoload.php'; use Aws\CognitoIdentityProvider\CognitoIdentityProviderClient; use Aws\Exception\AwsException; $client = new CognitoIdentityProviderClient([ 'region' => '你的Cognito区域(如us-east-1)', 'version' => 'latest', 'credentials' => [ 'key' => '你的AWS Access Key', 'secret' => '你的AWS Secret Key' ] ]); $userPoolId = '你的Cognito用户池ID'; $clientId = '你的Cognito应用客户端ID'; try { $result = $client->adminInitiateAuth([ 'UserPoolId' => $userPoolId, 'ClientId' => $clientId, 'AuthFlow' => 'ADMIN_NO_SRP_AUTH', 'AuthParameters' => [ 'LOGIN' => sprintf('cognito-idp.%s.amazonaws.com/%s:%s', $client->getRegion(), $userPoolId, $googleIdToken) ] ]); // 获取Cognito生成的令牌,可存入session用于后续身份校验 $authResult = $result->get('AuthenticationResult'); $cognitoIdToken = $authResult['IdToken']; $cognitoAccessToken = $authResult['AccessToken']; $cognitoRefreshToken = $authResult['RefreshToken']; // 跳转至登录后的页面 header('Location: /dashboard.php'); exit; } catch (AwsException $e) { die('Cognito认证失败:' . $e->getAwsErrorMessage()); } ?>
关键说明
- 如果是用户首次通过谷歌登录,Cognito会自动在用户池中创建该用户(需确保用户池配置允许自动创建用户)
- 后续可使用Cognito的
GetUser接口,通过Access Token获取用户详细信息,或直接解析ID Token获取用户邮箱、姓名等基础信息
内容的提问来源于stack exchange,提问作者abouterf
相关产品推荐
相关产品推荐

