繁体   English   中英

如何使用PHP在我的安全站点上显示受保护的Amazon S3映像?

[英]How do I display protected Amazon S3 images on my secure site using PHP?

我正在尝试将我的网站的图像从我的主机移动到Amazon S3云托管。 这些图像属于客户工作站点,无法公开。 我希望它们能够在我的网站上显示,最好是使用亚马逊提供的PHP SDK。

到目前为止,我已经能够为转换编写脚本,以便在数据库中查找记录,获取文件路径,对其进行适当命名,然后将其发送到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
    )
    );

在我复制所有内容之前,我创建了一个简单的表单来测试上传和显示图像。 如果我使用ACL_PRIVATE上传图像,我可以获取公共网址,但我无法访问,或者我可以使用临时密钥获取公共网址并显示图像。

<?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 />

使用这种方法,我的缓存将如何工作? 我猜每次刷新页面,或者修改我的一条记录,我都会再次拉动该图像,增加我的获取请求。

我还考虑使用存储桶策略仅允许从某些引用来检索图像。 我是否正确理解亚马逊应该仅从我指定的页面或域中获取请求?

我参考了: https//forums.aws.amazon.com/thread.jspa?messageID = 188183&#188183来设置它,但后来我对我的对象需要哪种安全性感到困惑。 看起来如果我将它们设为私有它们仍然不会显示,除非我使用前面提到的临时链接。 如果我将它们公之于众,我可以直接导航到它们,无论引荐者如何。

我是不是想在这里做什么? 这不是S3真的支持,还是我错过了一些简单的东西? 我已经完成了SDK文档和大量搜索,并且觉得这应该更清楚地记录下来,所以希望这里的任何输入都能在这种情况下帮助其他人。 我读过其他人用文件命名这个文件的唯一ID,通过默默无闻来创建安全性,但这不会在我的情况下削减它,对于任何想要保护安全的人来说,这可能不是最好的做法。

为图像提供服务的最佳方式是使用PHP SDK生成URL。 这样下载就会直接从S3发送到您的用户。

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

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

你显然必须在未来的某个地方设置到期时间,但如果你愿意的话,你可以经常重新生成这些网址。 例如,在您的数据库中,您将存储生成的URL和到期日期(您也可以从URL解析)。 然后,您只需使用现有的URL,或者如果过期日期已过,则生成一个新的URL。 等等...

您可以在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/*"
          ]
        }
      }
    }
  ]
}

当您谈论安全性并保护未经授权的用户数据时,有一些事情是明确的:您必须在每次访问您有权访问的资源时进行检查。

这意味着,生成一个可以被任何人访问的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');

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

举个粗略的例子,假设你在image.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">

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM