Эхо / распечатать JPG-изображение с PHP, для безопасности? - PullRequest
5 голосов
/ 14 сентября 2009

Из-за безопасности (проверьте, авторизован ли пользователь) я вызываю php-документ при показе изображений.

<html>...
<img src="showImage.php?id=455" />
...</html>


showImage.php:
<?php...

if($_SESSION['user']){
    //Get the src to the image
    $_GET[$id] = mysql_real_escape_string($_GET['id']); 
    $result = mysql_query("
        SELECT src
        FROM Media 
        WHERE id = '".$_GET['id']."'
        ");
    $data = mysql_fetch_assoc($resultat);

    // Output the image
    header('Content-Type: image/jpeg');
    echo(file_get_contents("media/".$data['src']));
}

...?>

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

Я не уверен, что это лучший способ. Есть ли более простой / лучший способ сделать это, и это безопасно. Когда сценарий повторяется, он немного медленный.

  • Я хочу, чтобы изображение было безопасным (только авторизованный пользователь должен иметь доступ к изображению)
  • Я хочу, чтобы изображение показывалось как можно быстрее

Ждем всех ваших советов экспертов.

Ответы [ 3 ]

10 голосов
/ 14 сентября 2009

Прежде всего, вместо чтения файла с file_get_contents и только затем, отображая его содержимое, вы можете использовать readfile: он будет выполнять обе операции в одном вызове - что будет вероятно, будет быстрее и использовать меньше памяти, чем:

  • загрузить полный файл в память с помощью file_get_only
  • и только после этого отправлять этот контент в outout


Затем, если вы хотите, чтобы только идентифицированный пользователь имел доступ к изображениям, у вас нет особого выбора: если ваш механизм идентификации основан на PHP, вам придется пройти через PHP, чтобы ограничить доступ к файлу - что да, это будет немного медленнее, чем при использовании Apache напрямую для обслуживания контента.


Также: здесь вы говорите:

Я надеюсь, что пользователь никогда не узнает прямой URL к изображению

Читая это, я предполагаю, что ваши изображения могут быть доступны напрямую через Apache, минуя ваш PHP-скрипт, если кто-то знает их URL; безопасность от неясности не хороша.

Лучшим решением, если вы не хотите, чтобы ваши изображения обслуживались Apache, было бы поместить их в каталог, из которого Apache ничего не будет обслуживать:

  • любой подкаталог вашего корневого документа, защищенный файлом .htaccess, содержащим "Deny from all"
  • или каталог, который не находится под вашим корневым каталогом и, следовательно, никогда не будет обслуживаться Apache.

В любом случае, это обеспечивает доступ к файлам только ваших сценариев, но не Apache напрямую, что означает, что пользователь не должен обходить сценарий.


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

Например, вас могут заинтересовать заголовки HTTP, такие как "Etag" и / или "Last-Modified".

2 голосов
/ 14 сентября 2009

Поскольку вам требуется, чтобы только зарегистрированные пользователи просматривали изображение, я бы сказал, что у вас нет выбора, когда дело доходит до этого. Вам придется продолжать делать это до тех пор, пока ваш сайт не станет безумно популярным, и в этот момент вы сможете определить более эффективную систему для нескольких серверов, используя более низкую проверку доступа, чем PHP (что стоит дорого). *

<?php

if($_SESSION['user']){

    $result = mysql_query("SELECT src FROM Media WHERE id = '"
    . mysql_real_escape_string($_GET['id']) ."'");

    $data = mysql_fetch_assoc($resultat);

    // Output the image
    header('Content-Type: image/jpeg');
    readfile("media/". $data['src']));
}
0 голосов
/ 14 сентября 2009

Паскаль МАРТИН прав, что readfile по сути то же самое, что и echo и file_get_contents. Я сомневаюсь, что есть какие-то существенные различия в производительности, но проще использовать readfile.

Чтобы разрешить только авторизованным пользователям просматривать изображения, поместите изображения за пределы своего веб-каталога. Используя readfile, вы можете получить файл из другого каталога. Таким образом, они никак не смогут получить к нему доступ, даже если будут угадывать URL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...