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

对接Google Calendar报OAuth2 invalid_client错误如何解决

invalid_client: Unauthorized 报错排查

这个错误是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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:40:36