我正在实施一个cron自动获取Google Play商店中的应用安装统计信息。因此,我需要从Google云端存储中下载文件并进行解析。我做了这个代码:
// Set scopes to authorize full control of Cloud Storage
$scopes = array("https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control");
// Create new Google Client
$client = new Google_Client();
// Set path to ServiceAccount's credentials and link them to Google Client
putenv('GOOGLE_APPLICATION_CREDENTIALS=../../libs/GoogleAPICredentials/client_credentials_CPTS.json');
$client->useApplicationDefaultCredentials();
$client->setScopes($scopes);
// Create new Google Service Storage object to handle our repository
$service = new Google_Service_Storage($client);
// Get content of GCS repository
$request = $service->objects->listObjects("MY_BUCKET");
// Settings folders, files, buckets, names
$sourceBucket = "pubsite_prod_rev_BUCKET_IDENTIFIER";
$sourceObject = "installs_MY_APP_IDENTIFIER_" . $date->format("Ym") . "_overview.csv";
$localFile = "../files/temp/installs_MY_APP_IDENTIFIER_" . $date->format("Ym") . "_overview.csv";
$fullSrcObj = "stats/installs/" . $sourceObject;
$destinationBucket = "MY_BUCKET";
$destinationObject = $sourceObject;
// Create new Google Service Storage StorageObject object to handle a single object (file)
$postBody = new Google_Service_Storage_StorageObject($client);
try {
// Copy stats app .CSV file from orignal repository (Google Play Store) to our bucket
$response = $service->objects->copy($sourceBucket, $fullSrcObj, $destinationBucket, $destinationObject, $postBody);
// Get the new object
try {
$object = $service->objects->get($destinationBucket, $destinationObject);
}
catch (Google_Service_Exception $e) {
if ($e->getCode() == 404)
echo ("[<b><span style=\"color:#DA4F34\">ERROR</span></b>] <b><span style=\"color:#DA4F34\">". $e->getMessage() ."</span></b><br><br>");
throw $e;
}
// Download the new object on the MY_COMPAGNY server
$uri = sprintf('https://storage.googleapis.com/%s/%s?alt=media&generation=%s', $destinationBucket, $destinationObject, $object->generation);
$http = $client->authorize();
$response = $http->get($uri);
if ($response->getStatusCode() != 200) {
echo ("[<b><span style=\"color:#DA4F34\">ERROR</span></b>] <b><span style=\"color:#DA4F34\">An unhandled error append !</span></b><br><br>");
die();
}
// Save it into local file on MY_COMPAGNY server
file_put_contents($localFile, $response->getBody());
// Convert .CSV into php array
$csv = array_map('str_getcsv', file($localFile));
// Delete local file
unlink($localFile);
// Remove last line of CSV (Array) --> Empty - And remove first line of CSV (Array) --> Title line
array_shift($csv);
array_pop($csv);
// Insert each line into MY_COMPAGNY Database
$success = false;
foreach ($csv as $row) {
$success = insertAppInstallData(filter_var($row[0], FILTER_SANITIZE_STRING), (int)filter_var($row[$columnTotal], FILTER_SANITIZE_NUMBER_INT), (int)filter_var($row[$columnCurrent], FILTER_SANITIZE_NUMBER_INT))?true: $success;
}
if (!$success)
echo ("[<b><span style=\"color:#DA4F34\">ERROR</span></b>] <b><span style=\"color:#DA4F34\">DataBase insertion failure</span></b><br><br>");
}
catch (Google_Service_Exception $E) {
echo ("[<b><span style=\"color:#DA4F34\">ERROR</span></b>] <b><span style=\"color:#DA4F34\">".$E->getMessage()." - ".$E->getTraceAsString()."</span></b><br><br>");
}
使用用户帐户,它运行良好,但有服务帐户,我有一个403错误,禁止通话 $ service-&gt; objects-&gt; copy()。
{
"error":
{
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "Forbidden"
}],
"code": 403,
"message": "Forbidden"
}
}
如果有良好的凭据,IAM授权,OAuth客户端,我会检查两次......并且它仍然无法正常工作。
我不是在谷歌引擎上,我在个人引擎上运行。
有人有想法吗?
祝你有个美好的一天和新年快乐!
本。
答案 0 :(得分:1)
您收到错误403的原因是您缺少域范围委派和用户模拟步骤。请参阅文档here以了解如何使用服务帐户访问用户数据。
这个过程是这样的:
$scopes = array("https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control");
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope($scopes); //Set scopes to client object
$client->setSubject("user@domain.com"); // replace with the user account
您可以使用用户帐户,因为用户已经可以访问资源而不能访问服务帐户,因此错误403被禁止。遗憾的是,域范围的委派流程和用户模拟仅适用于G Suite帐户(以前称为Google Apps)。 Antoher的替代方案是与服务帐户共享资源,但这是我尚未探索过的,不确定是否可能。您还可以参考PHP Client Lib文档here。我希望这些信息有用。