对接Google Calendar报OAuth2 invalid_client错误如何解决
这个错误是Google OAuth2流程中客户端身份校验不通过的典型报错,按以下优先级排查即可解决:
- 先核对Google Cloud控制台凭据配置
- 凭据类型必须选「Web 应用」,不能用桌面端、服务账号、移动端类型的Client ID/Secret
- 控制台配置的「已授权重定向URI」必须和代码里写的重定向地址完全一致,包括协议(http/https)、域名、路径、末尾斜杠,任何字符不匹配都会触发这个错误
- 复制Client ID、Client Secret时不要带多余空格,不要漏字符
- 再核对代码逻辑
- 你当前代码里
$client->authenticate($_GET['code'],true)的第二个参数crossClient只有跨同项目关联客户端授权的特殊场景才需要开,普通自有应用对接必须传false,开启后会额外校验客户端归属关系,普通场景开启直接触发鉴权失败 - 授权码是一次性的,用完即失效,不要刷新页面重复提交同一个code
- 校准服务器时间,OAuth2签名校验允许的时间误差不超过5分钟,服务器时间偏差过大也会报鉴权错误
- 你当前代码里
- 最后核对项目配置
- 如果你的Google Cloud项目处于测试阶段,必须把用于测试的Google账号加到项目的「测试用户」列表,否则非项目成员账号会被拦截
- 提前在Google Cloud控制台启用Google Calendar API,没开API的情况下即使OAuth授权通过也无法调用日历接口
可直接运行的对接代码
先在项目根目录执行命令安装官方稳定版Google客户端依赖:
composer require google/apiclient:^2.0
授权发起文件(比如auth.php)
<?php require __DIR__ . '/vendor/autoload.php'; // 替换为你自己的凭据信息 $clientId = '你的Web应用类型Client ID'; $clientSecret = '你的Client Secret'; $redirectUri = '你的回调地址,必须和控制台配置完全一致,例:https://你的域名/callback.php'; $client = new Google\Client(); $client->setClientId($clientId); $client->setClientSecret($clientSecret); $client->setRedirectUri($redirectUri); // 申请日历读写权限,可根据需求调整权限范围 $client->addScope(Google\Service\Calendar::CALENDAR); $client->setAccessType('offline'); // 需要获取刷新令牌实现长期授权则开启 $client->setPrompt('select_account consent'); // 跳转Google授权页 header('Location: ' . $client->createAuthUrl()); exit;
回调处理文件(callback.php,即上面配置的重定向URI对应文件)
<?php require __DIR__ . '/vendor/autoload.php'; // 凭据配置和auth.php保持完全一致 $clientId = '你的Web应用类型Client ID'; $clientSecret = '你的Client Secret'; $redirectUri = '你的回调地址,和上方、控制台配置完全一致'; $client = new Google\Client(); $client->setClientId($clientId); $client->setClientSecret($clientSecret); $client->setRedirectUri($redirectUri); $client->addScope(Google\Service\Calendar::CALENDAR); if (isset($_GET['code'])) { try { // 普通场景第二个参数固定传false,不要开启crossClient $token = $client->fetchAccessTokenWithAuthCode($_GET['code'], false); if (isset($token['error'])) { throw new Exception(json_encode($token)); } // 令牌可以存到会话或者数据库,后续调用接口直接取用 session_start(); $_SESSION['google_token'] = $token; $client->setAccessToken($token); // 测试调用日历接口,拉取最近10条即将到来的日程 $calendarService = new Google\Service\Calendar($client); $events = $calendarService->events->listEvents('primary', [ 'maxResults' => 10, 'orderBy' => 'startTime', 'singleEvents' => true, 'timeMin' => date('c') ])->getItems(); echo "对接成功,即将到来的日程:<br>"; if (!$events) { echo "无日程"; } else { foreach ($events as $event) { $startTime = $event->start->dateTime ?: $event->start->date; echo sprintf("- %s:%s<br>", $startTime, $event->getSummary()); } } } catch (Exception $e) { echo "调用出错:" . $e->getMessage(); } } else { echo "未获取到有效授权码"; }
内容的提问来源于stack exchange,提问作者kis
相关产品推荐
相关产品推荐

