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

Google Cloud Storage with Service account - 403 Forbidden

我正在实施一个 cron,自动获取我在 Google Play 商店上的应用程序安装统计信息。所以,我需要从 Google Cloud Storage 下载一个文件并解析它。我制作了这段代码:

// 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->objects->copy() .

{ 
   "error": 
   { 
        "errors": [ 
        { 
            "domain": "global", 
            "reason": "forbidden", 
            "message": "Forbidden" 
        }], 
        "code": 403, 
        "message": "Forbidden" 
    } 
}

我检查了两次是否有良好的凭据、IAM 授权、OAuth 客户端……但它仍然有效。

我不使用 Google 引擎,我 运行 使用个人引擎。

有人有想法吗?

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

本.

您收到错误 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)。另一种选择是与服务帐户共享资源,但这是我尚未探索过的事情,不确定是否可行。您还可以参考 PHP Client Lib 文档 here。希望这些信息对您有所帮助。