2

PHPでAPIv1.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

私が気づいたことの1つは、「stringToSign」変数に「PUT」を指定しても...応答は「GET」を使用したことを示していることです...?

どんな助けでもいただければ幸いです。

4

1 に答える 1

2

ここにはいくつかの問題があります。

  • 正規化されたリソースは、「/HTTP 1.1」ではなく「/bucket/」である必要があります。
  • 署名する文字列に 2 つのカスタム ヘッダー (x-goog-version と x-goog-project-id) を含める必要があります。
  • 署名する文字列には、Date: ヘッダーで送信されたタイムスタンプが含まれている必要があります。
  • CURLOPT_PUT を設定して、curl がデフォルトの GET 要求ではなく PUT 要求を送信することを認識できるようにする必要があります (これが、エラー応答が 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);
?>

PS Google Cloud Storage の HMAC 認証に関するすべての詳細は、https ://developers.google.com/storage/docs/reference/v1/developer-guidev1#authentication で提供されています。

于 2012-03-04T04:37:09.287 に答える