我觉得在这里发布这个很奇怪,但因为SO是Google API支持的唯一官方渠道,所以我想我需要在这里提问。为什么Google Storage API不能与Amazon SDK v3一起使用?
如果你有API,工具的使用,或其他软件开发相关的 问题,搜索和发布问题上堆栈溢出,使用 官方谷歌云存储标签。
好吧,所以这里。我花了两天的精力在尝试让Google Storage在亚马逊PHP SDK的v3版本(最新版本)上工作。我无法使用较旧版本的SDK,因为我试图坚持使用Laravel 5.1的文件系统,而无需为Google Storage编写全新的驱动程序。我相信这是一个什么样谷歌发布了谷歌存储的精神内:
https://cloud.google.com/storage/docs/migrating
在从Amazon S3到谷歌云存储的简单迁移,您可以 使用现有的工具和库用于生成已认证的 对Amazon S3的REST请求,还将已验证的请求发送至 Google云端存储。本部分描述了您需要对现有的 工具和库进行的更改。
若要设立一个简单的迁移执行以下操作:
设置默认的谷歌项目。
获取开发人员密钥。
在您现有的工具或库中,进行以下更改:将请求 端点更改为使用Google Cloud Storage请求端点。将 Amazon Web Services(AWS)访问和密钥替换为相应的 Google Cloud Storage访问密钥和密钥(统称为 您的Google开发人员密钥)。
就是这样!此时,您可以使用现有工具和库开始 向Google云端存储发送keyed-hash消息 认证码(HMAC)请求。
什么样的音调!让我们尝试使用使用gsutil的互操作性凭证。
$client = new S3Client([
'credentials' => [
'key' => 'GOOGxxxxxxxxxxxxxxx',
'secret' => 'ZfcOTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
],
'region' => 'US',
'version' => 'latest',
'endpoint' => 'https://storage.googleapis.com',
]);
try {
$result = $client->putObject(array(
'Bucket' => 'devtest',
'Key' => 'test',
'Body' => 'Hello world'
));
echo $result['ObjectURL'];
} catch (\Aws\S3\Exception\S3Exception $e) {
// The AWS error code (e.g.,)
echo $e->getAwsErrorCode() . "\n";
// The bucket couldn't be created
echo $e->getMessage() . "\n";
}
不起作用。您会收到“错误的身份验证标题”。我们来看看这个标题。
AWS4-HMAC-SHA256 凭证= GOOGGUxxxxxxxxxxx/20150611/US/S3/aws4_request, SignedHeaders =主机; X-AMZ-内容-SHA256; X-AMZ-日期, 签名= 9c7de4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
我在这里创建了一个关于此的SO帖子,有人建议我添加'signature'=>'v2'。
Google Storage Incorrect Authorization Header with Amazon S3 PHP SDK v3
让我们试试:
$client = new S3Client([
'credentials' => [
'key' => 'GOOGxxxxxxxxxxxxxxx',
'secret' => 'ZfcOTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
],
'region' => 'US',
'version' => 'latest',
'endpoint' => 'https://storage.googleapis.com',
'signature' => 'v2',
]);
没有运气。同样的错误。授权标头没有改变。让我们看看S3Client的代码,看看如何使用“签名”:
public function createPresignedRequest(CommandInterface $command, $expires)
{
/** @var \Aws\Signature\SignatureInterface $signer */
$signer = call_user_func(
$this->getSignatureProvider(),
$this->getConfig('signature_version'),
$this->getApi()->getSigningName(),
$this->getRegion()
);
return $signer->presign(
\Aws\serialize($command),
$this->getCredentials()->wait(),
$expires
);
}
它没有。所以,现在我们从S3的官方文档偏离,因为他们说同一件事:
http://docs.aws.amazon.com/aws-sdk-php/guide/latest/configuration.html
这不是“签名”,这是“signature_version”。让我们将其改为v2。
$client = new S3Client([
'credentials' => [
'key' => 'GOOGxxxxxxxxxxxxxxx',
'secret' => 'ZfcOTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
],
'region' => 'US',
'version' => 'latest',
'endpoint' => 'https://storage.googleapis.com',
'signature_version' => 'v2',
]);
这次至少我们得到了一个不同的错误!
UnresolvedSignatureException在SignatureProvider.php线61:无法 解决的V2/S3/US签名。有效签名版本包括 v4和匿名。
因此,在玩了两天之后,看起来这是不可能的,至少不会让Google想让你相信他们的音调。我根本无法得到这个工作,所以我希望这里有人能够阐明这一点。要么我错过了一些重要的事情,要么谷歌虚假宣传谷歌存储使用亚马逊的S3 SDK工作,并浪费开发者的时间。我在想,也许我们必须手动劫持授权头,但那不在我的专业知识范围之内。任何帮助将不胜感激。
将'version'设置为早于'latest',怎么办?没有尝试,只是在黑暗中拍摄。 – zaak
@zaak是的,我也试过。没有运气。 – Citizen
您可以比较gsutil auth头文件(可以用“gsutil -D ...”查看)与PHP SDK发送的不同吗? –