Echo / напечатать jpg-изображение с php, для безопасности?

Из-за безопасности (проверьте, зарегистрирован ли пользователь), я вызываю 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-адрес изображения, а при попытке показать изображение пользователь должен войти в систему.

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

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

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

Solutions Collecting From Web of "Echo / напечатать jpg-изображение с php, для безопасности?"

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

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

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

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

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

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

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

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

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

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

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

Поскольку вы требуете, чтобы только зарегистрированные пользователи просматривали изображение, я бы сказал, что у вас действительно нет выбора, когда дело доходит до этого. Вам придется продолжать делать это так, пока ваш сайт не станет безумно популярным, и в этот момент вы сможете определить более эффективную систему для нескольких серверов, используя проверку доступа на более низком уровне, чем 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'])); } 

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

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