【问题标题】:Google Cloud Storage Signed Url - SignatureDoesNotMatchGoogle Cloud Storage 签名网址 - SignatureDoesNotMatch
【发布时间】:2013-12-21 01:09:49
【问题描述】:

我可以使用 google-api-php-client 将文件 (image.png) 放到我的 Google Cloud Storage 存储桶中,但现在我无法尝试创建签名的 url 以从我的网站。示例代码:

$bucketName = 'bucket-name';
$id = 'image.png';
$serviceAccountName = '123456789-xxxx@developer.gserviceaccount.com';
$privateKey = file_get_contents($location_to_key_file);
$signer = new \Google_P12Signer($privateKey, "notasecret");
$ttl = time() + 3600;
$stringToSign = "GET\n" . "\n" . "\n" . $ttl . "\n". '/' . $bucketName . '/' . $id;
$signature = $signer->sign(utf8_encode($stringToSign));
$finalSignature = \Google_Utils::urlSafeB64Encode($signature);
$host = "https://".$bucketName.".storage.googleapis.com";
echo  $host. "/".$id."?GoogleAccessId=" . $serviceAccountName . "&Expires=" . $ttl . "&Signature=" . $finalSignature;

返回:

<Error><Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your  Google secret key and signing method.</Message>
<StringToSign>
GET 1387590477 /bucketname/image.png</StringToSign></Error>

我使用 google-api-php-client 和 php 5.5

我举了几个例子:

https://groups.google.com/forum/#!topic/gs-discussion/EjPRAWbWKbw

https://groups.google.com/forum/#!msg/google-api-php-client/jaRYDWdpteQ/xbNTLfDhUggJ

也许配置值没有正确传递? 我认为应该使用服务帐户电子邮件。还尝试在 $stringToSign 中包含 md5hash 和 content-type,结果相同。

任何帮助/提示将不胜感激。

【问题讨论】:

    标签: php google-api google-cloud-storage


    【解决方案1】:

    rdb 几乎可以为我解决问题。我为 python 使用了working python example from GoogleCloudPlatform,以调试 url 的问题并找到以下内容:

    • 必须对 GoogleAccessId 进行 urlencoded
    • 您必须在签名中替换以下字符:'-' => '%2B', '_' => '%2F
    • 签名必须以“%3D”结尾

    代码:

    $host. "/".$id."?Expires=" . $ttl . "&GoogleAccessId=" . 
            urlencode($serviceAccountName) . "&Signature=" . 
            str_replace(array('-','_',), array('%2B', '%2F'),urlencode($finalSignature)).'%3D';
    

    现在 url 应该可以工作了,你可以使用一些 advanced operators like response-content-disposition or response-content-type

    【讨论】:

    • 这就是我的答案。 :-) 我也忘了对 GoogleAccessId 电子邮件地址进行 url 编码。谢谢
    • 签名正确后(谢谢!)我不断收到 404 响应:“指定的密钥不存在。”。我试图检索一个名称中带有空格的文件,其中嵌套了一些“子目录”。原来我还需要做:$id = dirname($id) . '/' . rawurlencode(basename($id)); 有两件事需要注意:1)你必须使用 rawurlencode() 而不仅仅是 urlencode() 和 2)我没有尝试过带空格的路径,但是如果你 rawurlencode($id) 那么你'将被发送一个由 GCS 上的完整路径命名的文件,这可能不是你想要的。
    【解决方案2】:

    您可以尝试使用$host 来构造签名 URL -

    $host = "https://".$bucketName.".commondatastorage.googleapis.com";

    我发现与您所指的doc 有一个不同之处。

    谢谢

    【讨论】:

    • 更改子域后结果相同
    【解决方案3】:

    你能试试这个代码吗:)

    $finalSignature = base64_encode($signature);
    echo $host. "/".$id."?GoogleAccessId=" . $serviceAccountName . "&Expires=" . $ttl . "&Signature=" . urlencode($finalSignature);
    

    【讨论】:

      【解决方案4】:

      我认为您的错误在$finalSignature = \Google_Utils::urlSafeB64Encode($signature); 行中。此方法对 URL 做了一些奇怪的事情并替换了某些字符。

      最后我用下面的代码搞定了:

      $expires = time() + 60 * 30; // Half an hour
      
      // Get the key from the key file
      $privateKeyPath = Config::get('gcs.signing.key');
      $privateKey = file_get_contents($privateKeyPath);
      $signer = new Google_Signer_P12($privateKey, Config::get('gcs.signing.password'));
      
      //Signing does not like spaces, however it also doesn't like urlencoding or html entities
      $cloudStoragePath = str_replace(' ', '%20', $cloudStoragePath);
      
      //Create string to sign
      $stringToSign = "GET\n\n\n" . $expires . "\n" . "/" . $cloudStoragePath;
      
      //Sign
      $signature = $signer->sign(utf8_encode($stringToSign));
      
      $query = array(
          'GoogleAccessId' => Config::get('gcs.signing.service_account'),
          'Expires' => $expires,
          'Signature' => base64_encode($signature)
      );
      
      $url = self::$storageBaseUrl . '/' . $cloudStoragePath . '?' . http_build_query($query);
      

      【讨论】:

        猜你喜欢
        • 2014-03-22
        • 1970-01-01
        • 1970-01-01
        • 2019-06-11
        • 2018-05-03
        • 2019-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多