我有3个使用驱动器sdk的服务帐户。
1,有效,2有。
返回的错误是“刷新OAuth2令牌时出错,消息:'{”error“:”unauthorized_client“,”error_description“:”请求中未经授权的客户端或范围。“}'”
所有3个帐户都在开发者控制台中注册。 所有3个都有权在Google Apps控制台中进行“托管客户端API访问”。 所有3的范围都是“https://www.googleapis.com/auth/drive.readonly”。 驱动器中的所有3个文件夹都有一个特定的文件夹,用于“仅查看”。
我正在使用PHP并将一个参数传递给名为“type”的页面,并反映了该帐户的用途,1表示公开,1表示成员,1表示管理员。
例如
http://www.somehost.com/oauth_client.php?type=googledrive_admin
p12证书和用户值存储在服务器上。所有“ini”文件都具有相同的值结构,client_id,client_email,范围和查询过滤器。在所有情况下,文件之间唯一更改的项是client_id和client_email。
我的代码如下:
<?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) . "\n";
?>
每个ini文件的结构如下
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'"
我无法解决的问题是,当我为所有这些帐户完成相同的过程时,这适用于一个服务帐户而不适用于其他服务帐户。任何想法和帮助表示赞赏。
答案 0 :(得分:1)
感谢您发布此帖子以及您对“通过删除行$credentials -> sub = $service_account_email;
”解决的评论
我正面临类似的问题here。显然,$credentials -> sub = $service_account_email
仅适用于在Google Developers Console中创建的第一个/主要服务帐户。除此之外,它还会在某些OAuth2范围内产生意外错误(就像我在Fusion Tables中遇到的那样)。
因此,这里是一般建议:
不要不必要地包括
$credentials -> sub = $service_account_email
。
只有在你试图假冒时才这样做 差异用户(具有适当设置的条件) 已在Google Apps管理控制台中正确完成。
即使在某些情况下它可能不会产生任何错误,但在JWT声明集中包含服务帐户本身的电子邮件地址作为“子”字段的值时,会有一些意外的行为。