如何在没有客户端库的情况下授权在PHP中访问Google Cloud Storage API?

时间:2017-03-29 04:55:18

标签: php google-app-engine google-oauth google-cloud-storage

我想直接使用我自己的PHP代码访问Google云端存储API,因为Google的API库速度很慢,但我无法弄清楚如何获得授权。请参阅下面的代码。

我正在尝试在App Cloud Standard上运行的PHP代码中列出Google Cloud Storage存储桶中“目录”中的文件(即获取具有特定前缀的所有文件)。我发现在AppEngine上执行此操作的本机PHP函数(例如scandir())非常慢(> 1秒)。我也不是在谈论大型目录,也许是10个文件。

我也尝试使用Google APIs Client Library,特别是Objects方法,但发现它仍然很慢,但不是很糟糕,比如大约0.5秒。奇怪的是,当我计时时,实际的“Objects()”调用很快,它进入循环(“foreach($ objects as $ object)” - 但只是第一次迭代)这很慢!所以我认为图书馆可能在处理响应方面做了不必要的工作。我在"Try this API"中验证了这一点,查看了我的浏览器发出的请求,其中< 100毫秒。

因此,我想直接制作和处理API请求,而不是使用Google的慢速库。这是我写的准系统功能:

function get_files_from_gcs($dir, $data_storage_bucket) {
    $params = array(
        'delimiter' => '/',
        'prefix' => $dir,
        'fields' => 'items/name',);
    $query = http_build_query($params);
    $url = "https://www.googleapis.com/storage/v1/b/" . $data_storage_bucket . "/o?" . $query;
    log_error('Curl URL:'  . $url);
    //  Initiate curl
    $ch = curl_init();
    // Will return the response, if false it print the response
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    // Set the url
    curl_setopt($ch, CURLOPT_URL, $url);
    // Execute
    $result = curl_exec($ch);
    // Closing
    curl_close($ch);

    $data = json_decode($result, true);
    $filenames = array();
    foreach ($data as $item) {
        if (array_key_exists('name', $item)) {
            $filenames[] = $item['name'];
        }
    }

    return $filenames;
}

但是,我在响应中收到错误消息: “匿名用户没有storage.objects.list访问存储桶。”

我为我的存储桶设置了公共读取ACL,如下所示:

gsutil defacl ch -u AllUsers:R gs://<MY BUCKET>
gsutil -m acl -r set public-read gs://<MY BUCKET>

我还尝试在我的请求中设置'project'URL参数,和/或创建API密钥并设置'key'参数。没有骰子。

所以我认为我需要获得一个OAuth令牌(我认为这有点愚蠢 - 我的App Engine标准实例应该能够在没有任何特殊授权的情况下在同一个项目中向我的GCS发出请求......但是哦)。但老实说,我很失落如何做到这一点。我已经开始查看Google客户端API代码,但我无法确定实际发生的情况。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

如果我正确理解您的问题,您有一个可行的解决方案,但速度很慢。

在此基础上,我建议您使用混合方法。如果您当前正在使用该库进行身份验证,那么请保持该代码不做任何更改。它们来自php文档的关键位是: -

$token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
$client->setAccessToken($token);

这是您获得神奇的访问令牌的地方。完成后,您可以自由构建自己的http / rest调用。您需要做的就是将Access Token实例化为http Authorization标头,因此

  

授权:&#34; Bearer 4979e799a7979b79etc ...&#34;