Как отобразить защищенные изображения Amazon S3 на моем защищенном сайте с помощью PHP?


Я пытаюсь переместить изображения для своего сайта с моего хостинга на облачный хостинг Amazon S3. Эти изображения относятся к рабочим сайтам клиентов и не могут быть общедоступными. Я бы хотел, чтобы они отображались на моем сайте, предпочтительно с помощью PHP SDK, доступного на Amazon.

До сих пор мне удавалось создавать сценарии для преобразования, чтобы я просматривал записи в своей базе данных, брал путь к файлу, называл его соответствующим образом и отправлял на 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, я могу либо захватить общедоступный URL-адрес, и у меня не будет доступа, либо я могу захватить общедоступный URL-адрес с помощью временного ключа и отобразить изображение.

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

Используя этот метод, как будет работать мое кэширование? Я предполагаю, что каждый раз, когда я обновляю страницу или изменяю одну из своих записей, я буду снова извлекать это изображение, увеличивая свои запросы на получение.

Я также рассматривал возможность использования ведра политики, разрешающие извлечение изображений только от определенных источников. Правильно ли я понимаю, что Amazon должен получать запросы только с указанных мной страниц или доменов?

Я ссылался: https://forums.aws.amazon.com/thread.jspa?messageID=188183𭼗 чтобы настроить это, но затем я не понимаю, какая безопасность мне нужна на моих объектах. Казалось, что если бы я сделал их закрытыми, они все равно не отображались бы, если бы я не использовал временную ссылку, как упоминалось ранее. Если бы я сделал их достоянием общественности, Я мог бы перейти к ним напрямую, независимо от реферера.

Я далек от того, что пытаюсь здесь сделать? Действительно ли это не поддерживается S3, или я упускаю что-то простое? Я просмотрел документацию SDK и множество поисковых запросов и чувствую, что это должно быть немного более четко задокументировано, поэтому, надеюсь, любой вклад здесь может помочь другим в этой ситуации. Я читал других, которые называют файл уникальным идентификатором, создавая безопасность за счет неизвестности, но в моей ситуации это не поможет, и, вероятно, не лучшая практика для тех, кто пытается быть в безопасности.

Author: Bob, 2011-03-02

4 answers

Лучший способ обслуживания ваших изображений - создать URL-адрес с помощью PHP SDK. Таким образом, загрузки отправляются непосредственно с S3 вашим пользователям.

Вам не нужно загружать через свои серверы, как предложил @mfonda - вы можете установить любые заголовки кэширования, которые вам нравятся, на объектах S3, и если бы вы это сделали, вы бы потеряли некоторые основные преимущества использования S3.

Однако, как вы указали в своем вопросе, URL-адрес всегда будет меняться (фактически строка запроса), поэтому браузеры не будут кэшировать файл. Самый простой способ обойти это просто всегда использовать одну и ту же дату истечения срока действия, чтобы всегда создавалась одна и та же строка запроса. Или еще лучше "кэшировать" URL самостоятельно (например, в базе данных) и повторно использовать его каждый раз.

Очевидно, вам придется установить время истечения срока действия где-то в далеком будущем, но вы можете время от времени обновлять эти URL-адреса, если хотите. например, в вашей базе данных вы бы сохранили сгенерированный URL-адрес и дату истечения срока действия (вы также можете проанализировать это из URL-адреса). Тогда либо вы просто используете существующий URL-адрес или, если срок действия истек, создайте новый. и т.д....

 23
Author: Geoff Appleford, 2011-03-03 14:08:08

Вы можете использовать политики корзины в своей корзине 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/*"
          ]
        }
      }
    }
  ]
}
 8
Author: Wes, 2013-09-20 16:41:15

Когда вы говорите о безопасности и защите данных от неавторизованных пользователей, кое-что становится ясным: вы должны проверять каждый раз, когда получаете доступ к тому ресурсу, на который имеете право.

Это означает, что создание URL-адреса, к которому может получить доступ любой желающий (может быть трудно получить, но все же...). Единственное решение - это прокси-сервер изображения. Вы можете сделать это с помощью php-скрипта.

В блоге Amazon есть прекрасная статья, в которой предлагается использовать 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');
 2
Author: catalinux, 2015-01-20 22:10:15

Вы можете загрузить содержимое из 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">
 0
Author: mfonda, 2011-03-02 21:28:15