带有服务帐户的Google云端存储 - 403禁止访问

时间:2017-01-06 13:52:41

标签: php google-cloud-storage google-api-php-client google-play-services

我正在实施一个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客户端,我会检查两次......并且它仍然无法正常工作。

我不是在谷歌引擎上,我在个人引擎上运行。

有人有想法吗?

祝你有个美好的一天和新年快乐!

本。

1 个答案:

答案 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。我希望这些信息有用。