mil*_*non 6 php file-upload amazon-s3 amazon-web-services
我正在开发一个涉及生成S3 URL的项目,其他人可以使用它来将文件上传到我的S3存储桶.这是一个最小的工作示例:
<?php
require('aws.phar');
use Aws\S3\S3Client;
$s3client = new S3Client(...); // credentials go here
$id = uniqid(); // generate some kind of key
$command = $s3client->getCommand('PutObject', [
'ACL' => 'private',
'Body' => '',
'Bucket' => 'mybucket',
'Key' => 'tmp/' . $id]);
echo (string) $s3client->createPresignedRequest($command, '+5 minutes')->getURI();
?>
Run Code Online (Sandbox Code Playgroud)
现在,如果我将该文件放在互联网可访问的位置,我的网络服务器可用于获取新签名的上传网址:
$ curl http://my.domain.com/some/page.php
https://s3.amazonaws.com/mybucket/tmp/someID?x-amz-acl=private&lots-of-aws-params...
$ curl -X PUT -d "@someFile" https://s3.amazonaws.com/mybucket/tmp/someID?x-amz-acl=private&lots-of-aws-params...
$
Run Code Online (Sandbox Code Playgroud)
这会成功将本地文件上传到我的存储桶,因此我可以在S3中使用它.
让我们假设我不太担心人们会在很短的时间内生成许多URL并将许多文件上传到我的存储桶,但我想限制上传文件的大小.许多资源建议将策略附加到签名URL:
<?php
require('aws.phar');
use Aws\S3\S3Client;
$s3client = new S3Client(...); // credentials go here
$id = uniqid(); // generate some kind of key
$policy = [
'conditions' => [
['acl' => 'private'],
['bucket' => 'mybucket'],
['content-length-range', 0, 8*1024], // 8 KiB
['starts-with', '$key', 'tmp/']
], 'expiration' =>
(new DateTime())->modify('+5 minutes')->format(DateTime::ATOM)];
$command = $s3client->getCommand('PutObject', [
'ACL' => 'private',
'Body' => '',
'Bucket' => 'mybucket',
'Key' => 'tmp/' . $id,
'Policy' => $policy]);
echo (string) $s3client->createPresignedRequest($command, '+5 minutes')->getURI();
?>
Run Code Online (Sandbox Code Playgroud)
此版本生成可以以相同方式使用的URL(无任何错误指示).我不知道如果我需要一些这些条件的政策(以acl
,bucket
,starts-with
),但我不认为他们包括会打破政策.
理论上,尝试使用此签名URL上传大于8 KiB的文件应导致S3中止上载.但是,使用更大的文件对此进行测试表明curl
仍然可以愉快地上传文件:
$ ls -lh file.txt
-rw-rw-r-- 1 millinon millinon 210K Jan 2 00:41 file.txt
$ curl http://my.domain.com/some/page.php
https://s3.amazonaws.com/mybucket/tmp/someOtherID?x-amz-acl=private&lots-of-aws-params...
$ curl -X PUT -d "@file.txt" https://s3.amazonaws.com/mybucket/tmp/someOtherID?x-amz-acl=private&lots-of-aws-params...
$
Run Code Online (Sandbox Code Playgroud)
检查存储桶显示确实上传了大文件,并且文件的大小大于所谓的策略.
由于各种页面显示了附加策略的不同方式,我还尝试了以下版本:
'Policy' => json_encode($policy)
'Policy' => base64_encode(json_encode($policy))
Run Code Online (Sandbox Code Playgroud)
但是,使用任何这些版本生成的URL都允许上载大于指定大小的文件.
我是否错误地附加了该策略,或者是否存在以这种方式限制上传到S3的基本限制?
对于我的Web服务器,我使用的是适用于PHP的AWS SDK的3.14.1版HHVM 3.11.1.
S3 上传策略不能与预签名 URL 一起使用。
策略文档可以通过 HTML POST 表单通过浏览器上传到 S3 来使用。
预签名 URL和HTML POST 表单是上传到 S3 的两种不同方法。前者可以说比后者更简单,但灵活性较差。
更新
如果您必须在不使用浏览器的情况下上传文件,则可以使用 PHPcurl
函数、Guzzle等库或使用命令行来重现 HTML POST 表单的请求,如下所示:
curl 'https://s3-bucket.s3.amazonaws.com/' \
-F 'key=uploads/${filename}' \
-F 'AWSAccessKeyId=YOUR_AWS_ACCESS_KEY' \
-F 'acl=private' \
-F 'success_action_redirect=http://localhost/' \
-F 'policy=YOUR_POLICY_DOCUMENT_BASE64_ENCODED' \
-F 'signature=YOUR_CALCULATED_SIGNATURE' \
-F 'Content-Type=image/jpeg' \
-F 'file=@file.jpg'
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1370 次 |
最近记录: |