2

Ich implementiere einen Cron, der automatisch meine Anwendungsinstallationsstatistik im Google Play Store holt. Also muss ich eine Datei von Google Cloud Storage herunterladen und analysieren. Ich habe diesen Code:Google Cloud Storage mit Dienstkonto - 403 Forbidden

// 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>"); 
} 

Mit einem Benutzerkonto, ist es gut funktionieren, aber mit einem Dienstkonto, ich habe einen Fehler 403, Verbote auf dem Anruf zu $ service-> Objekte-> copy().

Ich überprüfe zweimal, ob es gute Anmeldeinformationen, IAM-Berechtigungen, OAuth-Client, ... und es noch dosent Arbeit gibt.

Ich bin nicht auf einer Google-Engine, ich laufe auf einer persönlichen Engine.

Jemand hat eine Idee?

Einen schönen Tag und ein gutes neues Jahr!

Ben.

Antwort

1

Der Grund, warum Sie Fehler 403 erhalten, liegt daran, dass Sie die domänenweite Delegierung und den Benutzeridentitätsschritt vermissen. In der Dokumentation here erfahren Sie, wie Sie mit Dienstkonten auf Benutzerdaten zugreifen können.

Der Prozess ist wie folgt aus:

$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("[email protected]"); // replace with the user account 

Sie sind in der Lage, um es mit einem Benutzerkonto funktioniert, da der Benutzer bereits Zugriff auf die Ressource hat aber nicht das Dienstkonto, damit der Fehler 403 verboten. Leider funktioniert der domänenweite Delegierungsprozess und der Benutzeridentitätswechsel nur mit G Suite-Konten (früher Google Apps). Antoher Alternative wäre, die Ressourcen mit dem Dienstkonto zu teilen, aber das ist etwas, das ich noch nicht erforscht habe und nicht sicher, ob es möglich ist. Sie können auch auf die PHP Client Lib-Dokumentation here verweisen. Ich hoffe, diese Information ist hilfreich.

+0

Danke für Ihre Antwort. Aber ich bekomme einen anderen Fehler: '" error_description ":" Nicht autorisierter Client oder Bereich in der Anfrage. "'. Warum ist mein Gültigkeitsbereich ungültig, während meine [email protected]_PROJECT.iam.gserviceaccount.com alle Berechtigungen in der Google Developer Console hat? Und wieso funktioniert es mit meinem Dienstkonto? –

+0

Verwenden Sie ein G Suite-Konto oder ein kostenloses Google Mail-Konto? – Morfinismo

+0

Ich verwende ein kostenloses Google Mail-Konto. Ich bezahle nur für Google Cloud Storage-Dienste. –

Verwandte Themen