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

调用Google People API时服务账号获取access token未授权报错问题

Google People API服务端调用报错排查

我正在为Web应用测试Google People API,操作步骤如下:

  • 我在Google控制台(https://console.cloud.google.com/)创建了新项目
  • 我启用了People API
  • 我创建了所需凭据:应用对应的Web客户端和API key
  • 我创建了带p12密钥的service account用于服务端间查询,同时开启了“Google Workspace Domain-wide Delegation”
  • 我配置了OAuth consent screen,设置了向Google授权并访问People API所需的scope:/auth/userinfo.email、/auth/userinfo.profile、/auth/contacts、/auth/contacts.readonly
  • 随后我使用“Google API PHP client”编写PHP脚本,生成指向同意屏幕的跳转链接,通过Web客户端获取用于换取access token的授权码:
<?php

$client = new Google_Client();

$client->setAccessType('online'); // default: offline
$client->setApplicationName('My Project xxxxx');
$client->setClientId('999999999999-qwertysdfhwe9uriiiiiiiiiiiiiiiii.apps.googleusercontent.com');
$client->setClientSecret('GOCSPX-hhhhhhhhhhhhhhhhhhhhhhhhhhhh');                
$client->setDeveloperKey('AIzafffffffffffffffffffffffffffffffffff'); // API key

$client->setState('subdomain.myapp.com');

$scriptUri = 'https://oauth.myapp.com/auth.php';
$client->setRedirectUri($scriptUri);

$client->addScope('https://www.googleapis.com/auth/userinfo.email');
$client->addScope('https://www.googleapis.com/auth/userinfo.profile');
$client->addScope('https://www.googleapis.com/auth/contacts');
                
$auth_url = $client->createAuthUrl();

header('Location: '.$auth_url);

?>

上述代码会跳转到Google身份验证页面,我登录Google账号并同意授权scope后,Google会重定向回我的应用,此时我已获取到access token、已授权scope列表以及已认证用户的邮箱。

后续步骤我遇到了无法解决的问题:通过服务端间查询的方式获取People API的access token时失败,相关代码如下:

function base64_url_encode($input) {
    return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
}

$iat = time();      

$url = "https://www.googleapis.com/oauth2/v4/token";        

$scope = 'https://www.googleapis.com/auth/contacts';

$jwt_data = array(
    'iss' => '111111111111111111111', // My service account ID
    'aud' => $url,
    'scope' => $scope,
    'exp' => $iat + 3600,
    'iat' => $iat,
    'sub' => 'user@gmail.com', // Email of the user that was autenticated in first step
);

openssl_pkcs12_read(file_get_contents('keyfile.p12'), $certs, 'notasecret');
$header = array('typ' => 'JWT', 'alg' => 'RS256');
$signing_input = base64_url_encode(json_encode($header)) . '.' . base64_url_encode(json_encode($jwt_data));
openssl_sign($signing_input, $signature, $certs['pkey'], 'SHA256');
$jwt = $signing_input . '.' . base64_url_encode($signature);

$data = array(
    "grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer",
    "assertion" => $jwt
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
curl_close($ch);

$google_contacts_api_tokens_collection[$use_mailbox] = $response;

return $response;

运行上述代码后Google返回了我无法解决的错误,目前暂无排查思路,错误信息如下:

原错误内容:"Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested."
中文翻译:客户端无权使用此方法获取访问令牌,或客户端未获得所请求的任何范围的授权


解决方案

按优先级逐一排查即可:

  1. 确认使用场景匹配授权逻辑
    你开启的Google Workspace全域委派仅对你自己企业域名下的账号生效,当前代码中sub字段填写的user@gmail.com是普通个人Google账号,不属于你的Workspace托管域,全域委派对个人账号完全无效,这类场景不需要用服务账号JWT流程,直接用第一步拿到的refresh token长期刷新access token调用接口即可。
    如果确实需要用服务账号访问,必须确保sub字段填写的是你企业域名下的内部邮箱,不能填gmail后缀的个人账号。
  2. 检查Workspace域scope授权配置
    如果是访问企业内部用户数据,需要进入Google Workspace管理后台的「API权限」->「全域委派权限」页面,找到对应服务账号的客户端ID,手动添加你用到的所有scope,保存后等待15分钟左右生效,未在此处添加的scope即使代码中请求也会被拒绝。
  3. 校验基础参数配置
    确认JWT中iss字段填写的是服务账号的完整邮箱(格式为xxx@xxx.iam.gserviceaccount.com),不是你当前填写的纯数字服务账号ID,参数填错是常见触发原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:45:03