Сбой запроса авторизации взаимодействия для облачного хранилища Google с ошибкой «подпись не совпадает» - PullRequest
2 голосов
/ 04 марта 2012

Я пытаюсь создать корзину в GCS, используя API v1.0 (режим взаимодействия) в PHP, но я получаю сообщение об ошибке «подпись не соответствует».

Вот что я делаю:


$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

Одна вещь, которую я заметил, это то, что, хотя я указываю «PUT» в переменной «stringToSign» ... в ответе говорится, что я использовал «GET» ...?

Любая помощь будет оценена.

1 Ответ

2 голосов
/ 04 марта 2012

Здесь есть несколько проблем:

  • Ваш канонизированный ресурс должен быть "/ bucket /", а не "/ HTTP 1.1".
  • Вам необходимо включить два пользовательскихзаголовки (x-goog-version и x-goog-project-id) в строке для подписи.
  • Строка для подписи должна включать метку времени, отправленную в заголовке Date: *
  • Youнеобходимо установить 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);
?>

PS Все подробности об аутентификации HMAC для Google Cloud Storage представлены здесь: https://developers.google.com/storage/docs/reference/v1/developer-guidev1#authentication

...