我正在使用aws-sdk-php创建预先签名的URL,以便将文件上传到S3存储桶。 GET的URL正在运行。
这是代码
$client = S3Client::factory(array('region' => 'eu-west-1','key' => 'xxx','secret' => 'xxx',));
//option 1
$command = $client->getCommand('PutObject', array(
'Bucket' => 'myBucket',
'Key' => 'testing/signedPHP1_'.time(),
'ContentType' => 'image/jpeg',
'Body' => 'dump' //it's mandatory
));
$signedUrl = $command->createPresignedUrl('+5 minutes');
$signedUrl .= '&Content-Type=image%2Fjpeg';
echo("\n\nThe URL is: ". $signedUrl . "\n");
echo("Now run from console for upload:\ncurl -v -H \"Content-Type: image/jpeg\" -T /tmp/temp.jpg '" . $signedUrl . "'");
//option 2
$request = $client->put('myBucket/testing/signedPHP2_'.time());
$signedUrl = $client->createPresignedUrl($request, '+5 minutes');
$signedUrl .= '&Content-Type=image%2Fjpeg';
echo("\n\nThe URL is: ". $signedUrl . "\n");
echo("Now run from console for upload:\ncurl -v -H \"Content-Type: image/jpeg\" -T /tmp/temp.jpg '" . $signedUrl . "'");
//GET which works
$request = $client->get('myBucket/testing/existingFile.txt');
$signedUrl = $client->createPresignedUrl($request, '+5 minutes');
echo("\n\nThe URL is: ". $signedUrl . "\n");
echo("Now run:\ncurl '" . $signedUrl . "'");
//GET which works
$command = $client->getCommand('GetObject', array('Bucket' => 'myBucket','Key' => 'upload/data.txt'));
$signedUrl = $command->createPresignedUrl('+5 minutes');
echo("\n\nThe URL is: ". $signedUrl . "\n");
echo("Now run:\ncurl '" . $signedUrl . "'");
当尝试使用curl命令时,我得到了错误 SignatureDoesNotMatch ,邮件我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法。
用于Javascript的aws-sdk中的类似代码正在运行
var AWS = require('aws-sdk');
AWS.config.update({ accessKeyId: 'xxx', secretAccessKey: 'xxx', region: 'eu-west-1' });
var s3 = new AWS.S3();
var params = {
Bucket: 'myBucket',
Key: 'testing/preSignedURLnodeJS_' + (+new Date),
ContentType: 'image/jpeg',
Expires: 60 * 5
};
s3.getSignedUrl('putObject', params, function(err, url) {
console.log('The URL is: ', url);
console.log('Now run from console for upload:\n\ncurl -v -H "Content-Type: image/jpeg" -T /tmp/temp.jpg \'' + url + '\'');
});
已经做了很多研究但没有结果。我究竟做错了什么?
答案 0 :(得分:8)
在Github上我得到了SDK开发人员的回答,它说
$command = $client->getCommand('PutObject', array(
'Bucket' => 'myBucket',
'Key' => 'testing/signedPHP1_'.time(),
'ContentType' => 'image/jpeg',
'Body' => '',
'ContentMD5' => false
));
答案 1 :(得分:0)
你走了:
首先,创建预先签名的网址
$activationCode = $request->activation_code;
$rules = [
'mc' => [
'required',
Rule::exists('email_verifications', 'machineCode')
->where(function ($query) use ($activationCode) {
$query->where('activationCode', $activationCode);
}),
],
'activation_code' => 'required|integer|min:5',
'operating_system' => 'required|alpha_num|max:45'
];
结果可能与此类似:
<?php
/**
* getDocumentUploadUrls
*
* creates a list of url so you can upload multiple files per
* document. After uploading the files it is requires for you
* to confirm the uploads.
*
* @param Int $documentId the document id
* @param Int $count the amount of files you want to upload for this document
*
* @return Array list of URLs to use with PUT request to upload files to s3.
*/
public function getDocumentUploadUrls(Int $documentId, Int $count = 1): Array
{
$awsService = $this->getService('aws');
$s3Client = $awsService->getSdk()->createS3();
$urls = array_fill(1, $count, null);
$bucket = 'yourbucket';
$result = [];
$expire = '+20 minutes';
for ($i = 0; $i < $count; $i++) {
$fileCount = $i + 1;
$key = "{$documentId}/{$fileCount}";
$cmd = $s3Client->getCommand('PutObject', [
'Bucket' => $bucket,
'Key' => $key
]);
$request = $s3Client->createPresignedRequest($cmd, $expire);
$result[] = [
'url' => (string) $request->getUri(),
'reference' => "{$bucket}/{$key}"
];
}
return $result;
}
现在,使用php cURL上传:
$result = [
0 => [
'url' => 'AwsS3://put/uri',
'reference' => 'docId/count'
]
];
答案 2 :(得分:-1)
如果您正在使用sdk,为什么不使用putObject命令,而不是自己创建一个put请求。这将为您处理signedUrl。
$result = $client->putObject(array(
'Bucket' => $bucket,
'Key' => 'data_from_file.txt',
'SourceFile' => $pathToFile
));
http://docs.aws.amazon.com/aws-sdk-php/latest/class-Aws.S3.S3Client.html#_putObject
如果您不想这样,您需要查看put命令的正文,这应该是您上传的文件的内容,而不仅仅是随机字符串'dump'。
在运行该命令的机器上运行wireshark,您将看到curl正在生成的请求正文是文件的内容。