计算引擎上的默认凭据消失

计算引擎上的默认凭据消失

您好,我创建了一个脚本,用于将一组图像文件公开为 Google 存储桶中的可读文件。稍后,另一个脚本将使它们再次变为私有文件。

该脚本在 GCE(Google 计算引擎)上运行。它开始运行良好,并将文件设置为公开,但在完成所有文件之前,它遇到了以下致命异常

Uncaught exception 'DomainException' with message 'Could not load the default credentials. in (...)/vendor/google/auth/src/ApplicationDefaultCredentials.php:148
Stack trace: 
    #0 (...)/vendor/google/apiclient/src/Google/Client.php(1053): Google\Auth\ApplicationDefaultCredentials::getCredentials('https://www.goo...') 
    #1 (...)/vendor/google/apiclient/src/Google/Client.php(354): Google_Client->createApplicationDefaultCredentials() 
    #2 (...)/vendor/google/apiclient/src/Google/Client.php(777): Google_Client->authorize() 
    #3 (...)/vendor/google/apiclient/src/Google/Service/Resource.php(232): Google_Client->execute(Object(GuzzleHttp\Psr7\Request), 'Google_Service_...') 
    #4 (...)/vendor/google/auth/src/ApplicationDefaultCredentials.php on line 148

我使用的代码如下。

require "../vendor/autoload.php";
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope(Google_Service_Storage::DEVSTORAGE_READ_WRITE);

$storage = new Google_Service_Storage($client);

$acl = new Google_Service_Storage_ObjectAccessControl();
$acl->setEntity('allUsers');
$acl->setRole('READER');

foreach($objects as $object){
    $files = $storage->objects->listObjects($GLOBALS["bucket"],array("prefix"=>$object->name()));
    $thumbs = $storage->objects->listObjects($GLOBALS["bucket"],array("prefix"=>"thumb/".$object->thumb()));
    $files = array_merge($files["items"],$thumbs["items"]);
    foreach($files as $file){
        if(strpos($file["name"],".pdf")===false)
        $storage->objectAccessControls->insert($GLOBALS["bucket"], $file["name"], $acl);
    }
}

有谁能告诉我为什么有时找不到默认凭据吗?

更新

我已更改代码,以便通过使用 php 的“exec”命令来使用“gsutil acl ch”命令。此操作没有任何问题,而且速度相当快,因为​​我可以使用 -m 参数以多进程方式运行 gsutil。

但为什么其他脚本有时无法检索默认凭据的问题仍然存在。我尝试将函数包装在 try/catch 块中,强制它在遇到异常时重试几次。在这些重试中,可以再次找到默认凭据,并且脚本继续在文件上设置 ACL,直到再次失败。

答案1

看起来 API 的 never 版本不会出现同样的问题。

新版本与旧版本略有不同。我没有创建 Google_Client 对象,而是一直使用他们的 ServiceBuilder。代码现在如下所示。

    $builder = new ServiceBuilder([
            'projectId' => "[projectID]",
            'keyFilePath' => "[keyFilePath]",
    ]);
    $bucket = $builder->storage()->bucket("[bucketName]");
    $objects = $this->bucket->objects(["prefix"=>"[PathPrefix]"]);
    foreach($objects as $object)
        $object->acl()->add("allUsers","READER");

相关内容