2016-05-30 68 views
1

我試圖在相當老的Web服務器上設置上傳過程,以便當用戶上傳新文件時,客戶端首先發送請求(沒有文件)到Web服務器,該服務器進行一些處理並返回一個預先簽名的URL,這將允許客戶端將文件直接上傳到S3。使用適用於PHP v2的AWS開發工具包爲文件上傳創建預定義的POST URL

需要注意的是,由於服務器上安裝了PHP版本,我正在使用適用於PHP的AWS開發工具包v2。

我可以使用下面的代碼來創建presigned網址:

$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,它被傳遞到客戶端。然而,在發送後續請求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是在文件上傳之前生成的,我不確定如何獲取該信息。

如果任何人都可以看到上述任何明顯錯誤,會導致此失敗,任何意見將不勝感激。

回答

0

您不能使用預先登錄的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的文檔中看到這一點。

+0

感謝您的幫助。我目前正在努力如何真正獲得SDK的請求所需的所有信息 - 你有什麼建議嗎? –

+0

我不確定這個特定的SDK會有多大的幫助。我一直寫所有我自己的代碼,用於請求籤名,策略生成等。不是PHP人員。 –

相關問題