【问题标题】:Creating a presigned POST URL for file upload with AWS SDK for PHP v2使用适用于 PHP v2 的 AWS 开发工具包创建用于文件上传的预签名 POST URL
【发布时间】:2016-05-30 14:32:51
【问题描述】:

我试图在一个相当旧的网络服务器上设置一个上传过程,这样当用户向它上传一个新文件时,客户端首先向网络服务器发送一个请求(没有文件),这会做一些处理并返回一个预签名的 URL,这将允许客户端将文件直接上传到 S3。

需要注意的是,由于服务器上安装的 PHP 版本,我使用的是 AWS SDK for PHP v2。

我可以使用以下代码创建预签名 URL:

$s3Client = Aws\S3\S3Client::factory(array(
    'key'    => "xxxxxxxxxxxxxxxxxxxx",
    'secret' => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
));

$command = $s3Client->getCommand('PutObject', array(
    'Bucket' => 'bucketname',
    'Key' => $this->_id.'/model.xyz',
    'Body' => '',
    'ContentMD5' => false,
    'ContentType' => 'multipart/form-data',
));

return $command->createPresignedUrl('+20 minutes');

这成功创建了一个 URL,该 URL 被传递给客户端。但是,在将后续请求发送到 S3 时,我收到此错误:

<?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 key and signing method.</Message>
    <AWSAccessKeyId>xxxxxxxxxxxxxxxxxxxxxxx</AWSAccessKeyId>
    <StringToSign>POST

    multipart/form-data; boundary=----WebKitFormBoundaryLFAYOUC0JsblZJHj
    1464614702
    /bucketname/blah/model.xyz</StringToSign>
    <SignatureProvided>xxxxxxxxxxxxxxxxxxxxxxxxxxx</SignatureProvided>
    <StringToSignBytes>xx xx xx xx xx xx xx xx xx xx xx...</StringToSignBytes>
    <RequestId>XXXXXXXXXXXXXXXXXXXX</RequestId>
    <HostId>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</HostId>
</Error>

我刚刚创建了所使用的访问密钥和密钥(用户拥有足够的权限),所以不正确的密钥不是问题。

请求标头:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:50145
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryLFAYOUC0JsblZJHj
Host:bucketname.s3.amazonaws.com
Origin:http://website.com
Pragma:no-cache
Referer:http://website.com/script.php
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36

此处显示的内容长度不同,但这很重要吗?鉴于 URL 是在文件上传之前生成的,我不确定如何获取该信息。

如果有人发现上述任何明显错误会导致此失败,任何建议将不胜感激。

【问题讨论】:

    标签: php amazon-s3 aws-sdk


    【解决方案1】:

    您不能使用预先签名的PUT URL 来上传POST。

    您使用签名的策略文档(base64 编码的 JSON 描述上传的允许属性)、签名和其他一些属性,例如实际文件的内容类型,所有这些都嵌入在表单中。

    对于签名版本 2,策略、签名和表单的构造在 http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingHTTPPOST.html 中进行了描述。

    对于签名版本 4,相同的信息位于 http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html。

    请注意,“签名版本”与 SDK 版本无关。所有地区都支持 Sig V4。 2014 年之前推出的区域也支持 Sig V2,这在某种程度上更容易从头开始实施。

    我提到了这一点,因为我在 PHP V2 SDK 的文档中根本没有看到这一点。

    【讨论】:

    • 感谢您的帮助。我目前正在努力解决如何从 SDK 获取请求所需的所有信息 - 你有什么建议吗?
    • 我不确定这个特定的 SDK 是否会有很大帮助。我一直为请求签名、策略生成等编写所有自己的代码。不过,我不是 PHP 人。
    猜你喜欢
    • 2018-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 2015-04-15
    • 2013-03-21
    • 1970-01-01
    相关资源
    最近更新 更多