27

I am trying to move images for my site from my host to Amazon S3 cloud hosting. These images are of client work sites and cannot be publicly available. I would like them to be displayed on my site preferably by using the PHP SDK available from Amazon.

So far I have been able to script for the conversion so that I look up records in my database, grab the file path, name it appropriately, and send it to Amazon.

    //upload to s3
$s3->create_object($bucket, $folder.$file_name_new, array(
    'fileUpload' => $file_temp,
    'acl' => AmazonS3::ACL_PRIVATE, //access denied, grantee only own
    //'acl' => AmazonS3::ACL_PUBLIC, //image displayed
    //'acl' => AmazonS3::ACL_OPEN, //image displayed, grantee everyone has open permission
    //'acl' => AmazonS3::ACL_AUTH_READ, //image not displayed, grantee auth users has open permissions
    //'acl' => AmazonS3::ACL_OWNER_READ, //image not displayed, grantee only ryan
    //'acl' => AmazonS3::ACL_OWNER_FULL_CONTROL, //image not displayed, grantee only ryan
    'storage' => AmazonS3::STORAGE_REDUCED
    )
    );

Before I copy everything over, I have created a simple form to do test upload and display of the image. If I upload an image using ACL_PRIVATE, I can either grab the public url and I will not have access, or I can grab the public url with a temporary key and can display the image.

<?php
//display the image link
$temp_link = $s3->get_object_url($bucket, $folder.$file_name_new, '1 minute');
?>
<a href='<?php echo $temp_link; ?>'><?php echo $temp_link; ?></a><br />
<img src='<?php echo $temp_link; ?>' alt='finding image' /><br />

Using this method, how will my caching work? I'm guessing every time I refresh the page, or modify one of my records, I will be pulling that image again, increasing my get requests.

I have also considered using bucket policies to only allow image retrieval from certain referrers. Do I understand correctly that Amazon is supposed to only fetch requests from pages or domains I specify?

I referenced: https://forums.aws.amazon.com/thread.jspa?messageID=188183&#188183 to set that up, but then am confused as to which security I need on my objects. It seemed like if I made them Private they still would not display, unless I used the temp link like mentioned previously. If I made them public, I could navigate to them directly, regardless of referrer.

Am I way off what I'm trying to do here? Is this not really supported by S3, or am I missing something simple? I have gone through the SDK documentation and lots of searching and feel like this should be a little more clearly documented so hopefully any input here can help others in this situation. I've read others who name the file with a unique ID, creating security through obscurity, but that won't cut it in my situation, and probably not best practice for anyone trying to be secure.

4

4 回答 4

25

提供图片的最佳方式是使用 PHP SDK 生成 url。这样,下载就直接从 S3 发送给您的用户。

你不需要像@mfonda 建议的那样通过你的服务器下载——你可以在 S3 对象上设置任何你喜欢的缓存头——如果你这样做了,你将失去使用 S3 的一些主要好处。

但是,正如您在问题中指出的那样,url 将始终在变化(实际上是查询字符串),因此浏览器不会缓存文件。简单的解决方法是始终使用相同的到期日期,以便始终生成相同的查询字符串。或者更好的是自己“缓存”url(例如在数据库中)并每次重用它。

您显然必须将到期时间设置在遥远的未来,但如果您愿意,您可以不时地重新生成这些 url。例如,在您的数据库中,您将存储生成的 url 和到期日期(您也可以从 url 解析它)。然后,您要么只使用现有的 url,要么,如果过期日期已过,则生成一个新的。ETC...

于 2011-03-03T14:08:08.697 回答
10

您可以在您的 Amazon 存储桶中使用存储桶策略来允许您的应用程序的域访问该文件。事实上,您甚至可以将您的本地开发域(例如:mylocaldomain.local)添加到访问列表中,您将能够获取您的图像。Amazon 在此处提供示例存储桶策略:http: //docs.aws.amazon.com/AmazonS3/latest/dev/AccessPolicyLanguage_UseCases_s3_a.html。这对帮助我提供图像非常有帮助。

下面的政策解决了让我想到这个 SO 主题的问题:

    {
       "Version":"2008-10-17",
       "Id":"http referer policy example",
       "Statement":[
    {
      "Sid":"Allow get requests originated from www.example.com and example.com",
      "Effect":"Allow",
      "Principal":"*",
      "Action":"s3:GetObject",
      "Resource":"arn:aws:s3:::examplebucket/*",
      "Condition":{
        "StringLike":{
          "aws:Referer":[
            "http://www.example.com/*",
            "http://example.com/*"
          ]
        }
      }
    }
  ]
}
于 2013-09-20T16:41:15.833 回答
2

当您谈论安全性和保护数据免受未经授权的用户的侵害时,有一点很清楚:每次访问您有权访问的资源时,您都必须进行检查。

这意味着,生成一个任何人都可以访问的 url(可能很难获得,但仍然......)。唯一的解决方案是图像代理。您可以使用 php 脚本来执行此操作。

亚马逊博客中有一篇很好的文章建议使用 readfile,http://blogs.aws.amazon.com/php/post/Tx2C4WJBMSMW68A/Streaming-Amazon-S3-Objects-From-a-Web-Server

readfile('s3://my-bucket/my-images/php.gif');
于 2015-01-20T22:10:15.610 回答
0

您可以从 S3 下载内容(在 PHP 脚本中),然后使用正确的标头提供它们。

举个粗略的例子,假设你有以下内容image.php

$s3 = new AmazonS3();
$response = $s3->get_object($bucket, $image_name);
if (!$response->isOK()) {
    throw new Exception('Error downloading file from S3');
}
header("Content-Type: image/jpeg");
header("Content-Length: " . strlen($response->body));
die($response->body);

然后在你的 HTML 代码中,你可以做

<img src="image.php">
于 2011-03-02T21:28:15.547 回答