Подтвердить что ты не робот

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

Вы можете использовать политики ведра в своем ковше Amazon, чтобы ваш домен приложения мог получить доступ к файлу. Фактически, вы даже можете добавить свой локальный домен dev (например: 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/*"
          ]
        }
      }
    }
  ]
}

Ответ 3

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

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

В блоге 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');

Ответ 4

Вы можете загрузить содержимое с S3 (в PHP script), а затем использовать их с помощью правильных заголовков.

Как пример, скажем, в 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">