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

Google API认证后如何将用户邮箱传递至重定向URI

解决方案:获取Google登录用户邮箱的补充步骤

当前你的OAuth2流程仅完成了access token的获取,但未调用Google用户信息API拉取邮箱数据。以下是具体补充步骤:

1. 在认证函数中添加用户信息获取逻辑

修改authenticate函数,在成功获取access token后,调用Google的Userinfo API获取用户邮箱,并将其存入Session:

function authenticate($scopes, $redirectUri) {
    $client = new \Google_Client();
    $client->setApplicationName("hidden");
    $client->setDeveloperKey(getenv('GOOGLE_API_KEY'));
    $client->setClientId(getenv('GOOGLE_API_ID'));
    $client->setClientSecret(getenv('GOOGLE_API_SECRET'));
    $client->setRedirectUri(site_url($redirectUri));
    foreach($scopes as $scope) {
        $client->addScope($scope);
    }

    try {
        if(!isset($_SESSION['google_access_token'])) {
            if(isset($_GET['code'])) {
                $client->fetchAccessTokenWithAuthCode($_GET['code']);
                $_SESSION['google_access_token'] = $client->getAccessToken();
                
                // 新增:调用Userinfo API获取用户邮箱
                $oauthService = new \Google_Service_Oauth2($client);
                $userProfile = $oauthService->userinfo->get();
                $_SESSION['google_user_email'] = $userProfile->getEmail();
            } else {
                $auth_url = $client->createAuthUrl();
                header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
                exit();
            }
        } else {
            // 检查token是否包含所有请求的权限
            $hasAllScopes = true;
            foreach($scopes as $scope) {
                if(!str_contains($_SESSION['google_access_token']['scope'], $scope)) {
                    $hasAllScopes = false;
                    break;
                }
            }
            
            if(!$hasAllScopes) {
                if(isset($_GET['code'])) {
                    $client->fetchAccessTokenWithAuthCode($_GET['code']);
                    $_SESSION['google_access_token'] = $client->getAccessToken();
                    
                    // 权限更新后重新获取邮箱
                    $oauthService = new \Google_Service_Oauth2($client);
                    $userProfile = $oauthService->userinfo->get();
                    $_SESSION['google_user_email'] = $userProfile->getEmail();
                } else {
                    $auth_url = $client->createAuthUrl();
                    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
                    exit();
                }
            } else {
                // 若token有效且权限齐全,直接拉取邮箱(防止Session中邮箱丢失)
                $client->setAccessToken($_SESSION['google_access_token']);
                $oauthService = new \Google_Service_Oauth2($client);
                $userProfile = $oauthService->userinfo->get();
                $_SESSION['google_user_email'] = $userProfile->getEmail();
            }
        }
    } catch (Exception $e) {
        return $e;
    }
}

2. 在重定向页面读取邮箱完成登录

在/users/google_signon_redirect对应的控制器方法中,从Session读取邮箱并执行登录逻辑:

public function google_signon_redirect() {
    // 检查Session中的邮箱是否存在
    if(isset($_SESSION['google_user_email'])) {
        $userEmail = $_SESSION['google_user_email'];
        // 执行你的登录逻辑:比如查找系统内用户、创建登录会话等
        // ...
        
        // 可选:清理临时Session数据
        unset($_SESSION['google_user_email']);
        unset($_SESSION['google_access_token']);
    } else {
        // 处理邮箱获取失败的情况,比如跳转回登录页
        header('Location: /login');
        exit();
    }
}

关于state变量的说明

state变量主要用于CSRF防护和传递自定义状态(比如用户原本访问的页面URL),和获取用户邮箱无关。邮箱是在用户授权后,通过access token调用Google API获取的,不需要通过state传递。如果需要使用state,可以在生成授权URL时添加:

// 在createAuthUrl前设置自定义state
$client->setState(base64_encode('your_custom_state'));
$auth_url = $client->createAuthUrl();

重定向后可通过$_GET['state']获取该值,但这不是获取邮箱的必要步骤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 17:06:10