Google 服务到服务身份验证不工作
Google Service to Service Authentication Not Working
我正在尝试让我的 php 应用程序调用 Google 的日历 API 使用服务到服务身份验证。我对我的 Education G Suite 拥有管理权限,并按照此处所示执行了以下步骤:https://developers.google.com/identity/protocols/OAuth2ServiceAccount
- 创建了一个具有全域权限的服务帐户,并保存了正确的凭据。
- 使用我的 ClientID(由 UI 确认)
将日历(读写)https://www.googleapis.com/auth/calendar 范围添加到我的管理员帐户 "Managed API Client Access"
- 对 php API 客户端进行了适当的调用,根据示例尝试同时模拟管理员和另一个用户帐户
这里:https://developers.google.com/api-client-library/php/auth/service-accounts
但是,当我尝试获取任何日历信息时,我继续收到以下错误:
Google_Service_Exception: { "error": "unauthorized_client", "error_description": "Client is unauthorized to retrieve access tokens using this method." }
根据谷歌搜索,这通常意味着我没有委托域范围的权限,但我肯定有。我已经尝试了其他 Google api,结果相同。
这是我的代码。感谢您的任何想法或帮助。
<?php require_once __DIR__ . '/vendor/autoload.php';
putenv('GOOGLE_APPLICATION_CREDENTIALS=****/client_secret.json');
$user_to_impersonate = 'user@****.com';
$user_scopes = array(
Google_Service_Calendar::CALENDAR
);
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->setSubject($user_to_impersonate);
$client->setScopes($user_scopes);
$client->setAccessType('offline');
$calendar = new Google_Service_Calendar($client);
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => TRUE,
'timeMin' => date('c'),
);
$results = $calendar->events->listEvents($calendarId, $optParams);
...
?>
Client is unauthorized to retrieve access tokens using this method.
当您在 Google 开发者控制台上创建项目时,您应该已经创建了服务帐户凭据。然后,系统会提示您下载一个文件,该文件包含服务帐户的凭据。
您用于连接到服务帐户的代码与用于使用浏览器或本机客户端凭据进行连接的代码不同。
ServiceAccount.php link to code
require_once __DIR__ . '/vendor/autoload.php';
// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');
/**
* Gets the Google client refreshing auth if needed.
* Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
* Initializes a client object.
* @return A google client object.
*/
function getGoogleClient() {
return getServiceAccountClient();
}
/**
* Builds the Google client object.
* Documentation: https://developers.google.com/api-client-library/php/auth/service-accounts
* Scopes will need to be changed depending upon the API's being accessed.
* array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
* List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
* @return A google client object.
*/
function getServiceAccountClient() {
try {
// Create and configure a new client object.
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope([YOUR SCOPES HERE]);
return $client;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
您似乎使用了正确的服务帐户代码。但是,您可能下载了错误的凭据文件,我建议您再次从 Google 开发人员控制台下载该文件。
在上面的第 2 步中添加了不正确的范围。希望这仍然能让一些人看到正确的步骤。
我也 运行 遇到过这个问题,但仅限于使用 $client -> setSubject(impersonationemail);
尝试注释掉这一行并查看它给您的响应代码。
我正在尝试让我的 php 应用程序调用 Google 的日历 API 使用服务到服务身份验证。我对我的 Education G Suite 拥有管理权限,并按照此处所示执行了以下步骤:https://developers.google.com/identity/protocols/OAuth2ServiceAccount
- 创建了一个具有全域权限的服务帐户,并保存了正确的凭据。
- 使用我的 ClientID(由 UI 确认) 将日历(读写)https://www.googleapis.com/auth/calendar 范围添加到我的管理员帐户 "Managed API Client Access"
- 对 php API 客户端进行了适当的调用,根据示例尝试同时模拟管理员和另一个用户帐户 这里:https://developers.google.com/api-client-library/php/auth/service-accounts
但是,当我尝试获取任何日历信息时,我继续收到以下错误:
Google_Service_Exception: { "error": "unauthorized_client", "error_description": "Client is unauthorized to retrieve access tokens using this method." }
根据谷歌搜索,这通常意味着我没有委托域范围的权限,但我肯定有。我已经尝试了其他 Google api,结果相同。
这是我的代码。感谢您的任何想法或帮助。
<?php require_once __DIR__ . '/vendor/autoload.php';
putenv('GOOGLE_APPLICATION_CREDENTIALS=****/client_secret.json');
$user_to_impersonate = 'user@****.com';
$user_scopes = array(
Google_Service_Calendar::CALENDAR
);
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->setSubject($user_to_impersonate);
$client->setScopes($user_scopes);
$client->setAccessType('offline');
$calendar = new Google_Service_Calendar($client);
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => TRUE,
'timeMin' => date('c'),
);
$results = $calendar->events->listEvents($calendarId, $optParams);
...
?>
Client is unauthorized to retrieve access tokens using this method.
当您在 Google 开发者控制台上创建项目时,您应该已经创建了服务帐户凭据。然后,系统会提示您下载一个文件,该文件包含服务帐户的凭据。
您用于连接到服务帐户的代码与用于使用浏览器或本机客户端凭据进行连接的代码不同。
ServiceAccount.php link to code
require_once __DIR__ . '/vendor/autoload.php';
// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');
/**
* Gets the Google client refreshing auth if needed.
* Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
* Initializes a client object.
* @return A google client object.
*/
function getGoogleClient() {
return getServiceAccountClient();
}
/**
* Builds the Google client object.
* Documentation: https://developers.google.com/api-client-library/php/auth/service-accounts
* Scopes will need to be changed depending upon the API's being accessed.
* array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
* List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
* @return A google client object.
*/
function getServiceAccountClient() {
try {
// Create and configure a new client object.
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope([YOUR SCOPES HERE]);
return $client;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
您似乎使用了正确的服务帐户代码。但是,您可能下载了错误的凭据文件,我建议您再次从 Google 开发人员控制台下载该文件。
在上面的第 2 步中添加了不正确的范围。希望这仍然能让一些人看到正确的步骤。
我也 运行 遇到过这个问题,但仅限于使用 $client -> setSubject(impersonationemail); 尝试注释掉这一行并查看它给您的响应代码。