如何在PHP中调用Google API验证access_token获取用户信息
问题诊断与修复方案
原代码核心错误
- 逻辑顺序颠倒:在
Google_Client实例化之前就调用了$google_client->authenticate()方法,且该方法是用于授权码code换token的场景,你的需求是直接验证用户传入的access_token,完全不需要这行代码 - 未获取用户传入的token:代码中
$token['access_token']属于未定义变量,没有从请求中读取用户传入的token值,导致setAccessToken传入空值,最终getAccessToken()一直返回false,触发返回登录URL的逻辑 - 冗余初始化代码:重复实例化了两次
Google_Client、两次Google_Service_Oauth2,属于无效代码 - 缺少异常捕获:access_token过期、伪造、作用域不足时会抛出异常,原代码没有捕获处理,会直接报错而非返回正确的错误提示
正确实现方案
首先通过composer安装Google官方PHP客户端:composer require google/apiclient:^2.0
可直接运行的实现代码:
<?php require __DIR__ . '/vendor/autoload.php'; // 初始化Google客户端 $google_client = new Google_Client(); $google_client->setClientId('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com'); // 替换为你的ClientID $google_client->setClientSecret('xxxxxxxxxxxxxxxxxxxxx'); // 替换为你的Client Secret $google_client->setRedirectUri('xxxxxxxxxxxx'); // 替换为Google控制台配置的Redirect Uri $google_client->addScope('email'); $google_client->addScope('profile'); $objOAuthService = new Google_Service_Oauth2($google_client); $outputjson = []; // 读取用户传入的access_token,同时支持GET参数和Authorization Bearer头两种传参方式 $access_token = isset($_GET['access_token']) ? $_GET['access_token'] : ''; if (empty($access_token) && isset($_SERVER['HTTP_AUTHORIZATION'])) { $authHeader = $_SERVER['HTTP_AUTHORIZATION']; if (preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) { $access_token = $matches[1]; } } if (empty($access_token)) { $outputjson['error'] = '缺少access_token参数'; echo json_encode($outputjson); exit; } try { // 把用户传入的token设置到客户端 $google_client->setAccessToken($access_token); // 先判断token是否过期 if ($google_client->isAccessTokenExpired()) { $outputjson['error'] = 'access_token已过期'; echo json_encode($outputjson); exit; } // 拉取用户信息 $userData = $objOAuthService->userinfo->get(); if (!empty($userData)) { $outputjson['user_data'] = $userData; $outputjson['access_token'] = $google_client->getAccessToken(); } else { $outputjson['error'] = '无法获取用户信息'; } } catch (Exception $e) { // token伪造、作用域不足、无效等异常统一处理 $outputjson['error'] = 'access_token无效'; } echo json_encode($outputjson);
Postman测试方式:
- 直接发送GET请求,携带参数
?access_token=用户提供的token值 - 或者在请求头中添加
Authorization: Bearer 用户提供的token值
内容的提问来源于stack exchange,提问作者Ritika
相关产品推荐
相关产品推荐

