问题描述
我有 3 个使用驱动 sdk 的服务帐户.
I have 3 service accounts that are using the drive sdk.
1 有效,2 无效.
返回的错误是Error refresh the OAuth2 token, message: '{ "error" : "unauthorized_client", "error_description" : "Unauthorized client or scope in request." }'"
The error that comes back is "Error refreshing the OAuth2 token, message: '{ "error" : "unauthorized_client", "error_description" : "Unauthorized client or scope in request." }'"
所有 3 个帐户均已在开发者控制台中注册.所有这 3 个都被授权在 Google Apps 控制台中进行托管客户端 API 访问".所有 3 都具有范围https://www.googleapis.com/auth/drive.readonly".驱动器中的所有 3 个,都有一个特定的文件夹供仅查看"共享.
我正在使用 PHP,我向页面传递了一个参数,该参数称为类型",它反映了帐户的用途,1 用于公共,1 用于会员,1 用于管理员.
http://www.somehost.com/oauth_client.php?type=googledrive_admin
<?php
include (__DIR__ . "/google-api-php-client/autoload.php");
google_api_php_client_autoload("Google_Auth_AssertionCredentials");
google_api_php_client_autoload("Google_Client");
google_api_php_client_autoload("Google_Service_Drive");
google_api_php_client_autoload("Google_Service_OAuth2");
$type = $_GET['type'];
$path = __DIR__ . "/secure/";
$certificate = $path . $type . ".p12";
$ini_path = $path . $type . ".ini";
$ini = parse_ini_file($ini_path);
$service_scope = $ini['scope'];
$service_account_id = $ini['id'];
$service_account_email = $ini['email'];
$service_query = $ini['q'];
$service_account_key = file_get_contents($certificate);
$credentials = new Google_Auth_AssertionCredentials(
$service_account_email,
array($service_scope),
$service_account_key
);
$credentials -> sub = $service_account_email;
$google_client = new Google_Client();
$google_client -> setAssertionCredentials($credentials);
if ($google_client -> getAuth() -> isAccessTokenExpired()) {
$google_client -> getAuth() -> refreshTokenWithAssertion(); **//FAILS HERE**
}
$drive = new Google_Service_Drive($google_client);
$result = array();
$pageToken = NULL;
do {
try {
$parameters = array();
if ($pageToken) {
$parameters['pageToken'] = $pageToken;
}
$parameters['q'] = $service_query;
$files = $drive -> files -> listFiles($parameters);
$result = array_merge($result, $files -> getItems());
$pageToken = $files -> getNextPageToken();
} catch (Exception $e) {
print "An error occurred: " . $e -> getMessage();
$pageToken = NULL;
}
} while ($pageToken);
echo json_encode($result) . "
";
?>
Each ini file is structured as follows
id="35{code}.apps.googleusercontent.com"
email="35{code}@developer.gserviceaccount.com"
scope="https://www.googleapis.com/auth/drive.readonly"
q="mimeType != 'application/vnd.google-apps.folder'"
我无法弄清楚为什么当我对所有服务帐户都进行了相同的过程时,这对一个服务帐户而不是其他服务帐户有效.任何想法和帮助表示赞赏.
推荐答案
感谢您的这篇文章以及您对Resolved by remove the line $credentials -> sub = $service_account_email;
"
我面临着类似的问题 这里.显然, $credentials ->sub = $service_account_email
仅适用于在 Google Developers Console 中创建的第一个/主要服务帐户.除此之外,它还会在某些 OAuth2 范围内产生意外错误(就像我在 Fusion Tables 中遇到的那样).
I am facing a similar issue here. Apparently, $credentials -> sub = $service_account_email
is only accepted for the first/primary service account created in the Google Developers Console. Besides that, it will also produce unexpected errors with certain OAuth2 scopes (as what I encountered with Fusion Tables).
因此,这里是一般建议:
Hence, here is the general advise:
不要包含 $credentials ->sub = $service_account_email
不必要.
仅当您尝试冒充差异用户(条件是适当的设置具有已在 Google Apps 管理控制台中正确完成).
尽管在某些情况下它可能不会产生任何错误,但在将服务帐户本身的电子邮件地址包含在 JWT 声明集中作为sub"字段的值时,会出现一些意外行为.
这篇关于谷歌驱动服务帐户和“请求中的未经授权的客户端或范围"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!