php - 谷歌云存储的互操作访问授权请求失败,出现 'signature does not match' 错误

标签 php http google-cloud-storage

我尝试使用 PHP 中的 API v1.0(互操作模式)在 GCS 上创建存储桶,但收到“签名不匹配”错误响应。

这就是我正在做的事情:


$access_id = "GOOGxxxxxx";
$secret_key = "xyxyxyxyx/xyxyxyxyx";
$bucket = "random_bucket_name";
$url = 'https://'.$bucket.'commondatastorage.googleapis.com';
$timestamp  = date("r");

$canonicalizedResources = "/ HTTP 1.1";
$stringToSign = utf8_encode("PUT "."\n"."\n"."\n".$canonicalizedResources);
$signature  = base64_encode(hash_hmac("sha1",$stringToSign,$secret_key,true));
$authSignature = $access_id.":".$signature;

$headers = array('Host: '.$bucket.'.commondatastorage.googleapis.com',
           'Date: '.$timestamp, 'x-goog-api-version: 1', 
           'x-goog-project-id: xxxyyyxy','Content-Length: 0',
           'Authorization: GOOG1 '.$authSignature);

$c   = curl_init($url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c,CURLOPT_HTTPHEADER,$headers);
$xml = curl_exec($c);

这是我得到的回复:

<?xml version='1.0' encoding='UTF-8'?>
 <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


   Sat, 03 Mar 2012 14:56:53 -0800
   x-goog-api-version:1
   x-goog-project-id:xxxyyyxy
   /random_bucket_name/
  </StringToSign>
 </Error>

有什么想法我哪里出错了吗?

以下是 Google 的相关文档: https://developers.google.com/storage/docs/reference-methods#putbucket

我注意到的一件事是,即使我在“stringToSign”变量中指定“PUT”...响应说我使用了“GET”...?

如有任何帮助,我们将不胜感激。

最佳答案

这里有一些问题:

  • 您的规范化资源应该是“/bucket/”,而不是“/HTTP 1.1”。
  • 您需要在要签名的字符串中包含两个自定义 header (x-goog-version 和 x-goog-project-id)。
  • 要签名的字符串必须包含在 Date: header 中发送的时间戳。
  • 您需要设置 CURLOPT_PUT,以便curl 知道发送 PUT 请求,而不是默认的 GET 请求(这就是您的错误响应暗示 GET 请求的原因)。

这是代码的更正版本,我对其进行了测试并用于创建新存储桶:

<?php
  $access_id = "REDACTED";
  $secret_key = "REDACTED";
  $bucket = "your-bucket";
  $url = 'https://'.$bucket.'commondatastorage.googleapis.com';
  $timestamp  = date("r");
  $version_header = "x-goog-api-version:1";
  $project_header = "x-goog-project-id:REDACTED";
  $canonicalizedResources = "/".$bucket."/";
  $stringToSign = utf8_encode("PUT\n\n\n".$timestamp."\n".$version_header."\n".$project_header."\n".$canonicalizedResources);
  $signature  = base64_encode(hash_hmac("sha1",$stringToSign,$secret_key,true));
  $authSignature = $access_id.":".$signature;

  $headers = array('Host: '.$bucket.'.commondatastorage.googleapis.com',
                   'Date: '.$timestamp, $version_header,
                   $project_header,'Content-Length: 0',
                   'Authorization: GOOG1 '.$authSignature);

  $c   = curl_init($url);
  curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($c,CURLOPT_HTTPHEADER,$headers);
  curl_setopt($c, CURLOPT_PUT, TRUE);
  $xml = curl_exec($c);
  print($xml);
?>

附注此处提供了有关 Google Cloud Storage HMAC 身份验证的所有详细信息:https://developers.google.com/storage/docs/reference/v1/developer-guidev1#authentication

关于php - 谷歌云存储的互操作访问授权请求失败,出现 'signature does not match' 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9550662/

相关文章:

php - Reactphp进程状态统计(空闲、工作等)

http - 使用 JAX-RS 的 "fake"DELETE 和 PUT 方法的最佳方法是什么?

google-cloud-storage - 谷歌云 : Using gsutil to download data from AWS S3 to GCS

http - 使用范围的拒绝服务攻击

python - 如何将 blob 复制到存储桶中的特定文件夹?

google-cloud-storage - 在 google 计算中创建磁盘时出错(未找到资源 '... diskTypes/{pd-ssd}'

php - 在 Codeigniter 上创建权限而不检查 URI 段

php - 根据日期和时间列出事件

PHP 嵌套 for 循环

linux - 如何使用 linux 使用 tcpdump 仅捕获 http