Контроль доступа к файлам на основе значений БД с помощью PHP / Apache - PullRequest
8 голосов
/ 17 мая 2011

Что я хочу

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

Теперь, когда пользователь загружает изображение, оно выполняется вместе со вставкой строки в базу данных MySQL, где изображение получает идентификатор, а строка содержит значение, определяющее, доступны ли изображения для общественности (1 только для большого пальца, 2 для обоих) вместе с владельцем (администратором) изображения.

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

Что я представляю

Если бы это можно было сделать с помощью php, я представляю что-то вроде этого:

//User tries to go to URL "images/IMAGE-ID_thumb.jpg"
if($img['access'] >= 1 || $_SESSION['admin_ID'] == $img['owner_ID']) {
  //Show image thumb
}
else {
  //Access denied
}

Я мог бы, возможно, спрятать изображения в защищенной папке .htaccess, создать imgae_get.php, который принимает переменные URL-адреса, проверяет, доступно ли изображение, и загружает ли изображение в таком случае. Я просто хочу избежать декомпиляции образа и других процессов, потребляющих энергию на сервере.

У меня вопрос, могу ли я управлять изображением, как это? Есть ли способ заставить скрипт php выглядеть как изображение, которое он загружает внутри? Или есть какой-то другой / лучший способ, чем через PHP? (Возможно, Apache?) Любые предложения очень ценятся.

Ответы [ 4 ]

4 голосов
/ 17 мая 2011

Вы можете перенаправить все запросы на определенные типы файлов (или имена файлов, все, что вы можете откорректировать) с помощью файла .htaccess в вашем DocumentRoot:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule \.(gif|jpg|jpeg|png)$ imageHandler.php [NC,L]

Вы можете определить исходный запрос из$_SERVER superglobal и используйте соответствующие заголовки, чтобы предупредить браузер, что вы возвращаете изображение.Затем вы читаете изображение с диска (с file_get_contents() или аналогичным) и записываете его в браузер с echo, так же, как вы выводили бы HTML.

4 голосов
/ 17 мая 2011
//get_image.php

//Do session/mysql checks as outlined in your code above.

header("Content-Disposition: filename=$imagename.$filetype");
header("Content-type: $mimetype");
readfile(PROTECTED_IMAGE_FOLDER . "$imagename.$filetype");
3 голосов
/ 17 мая 2011

.htaccess

#mod_rewrite
RewriteRule ^(.*)_(full|thumb).(jpg|png|gif)$ image.php?i=$1&type=$2&ext=$3

HTML

<img src="http://example.com/image-1_thumb.png" />
=
<img src="image.php?i=image-1&type=thumb&ext=png" />

PHP (image.php)

<?php 
// do basic sanity checks on input
$_GET['i'] = isset($_GET['i']) ? basename($_GET['i']) : null;
$_GET['type'] = isset($_GET['type']) ? basename($_GET['type']) : null;
//unsafe way
//$_GET['ext'] = isset($_GET['ext']) ?  basename($_GET['ext']) : null;
//safe way
$_GET['ext'] = in_array($_GET['ext'], array('png','gif', 'png')) ? $_GET['ext'] : null;

## Do DB Checks on session to owner ect 
/* $_GET
    [i] => image-1
    [type] => thumb
    [ext] => png
*/

// then output
if (file_exists('hiddenimagesfolder/images/'.$_GET['i'].'_'.$_GET['type'].'.'.$_GET['ext'])) {
    header("Content-Type:image/png");
    readfile('hiddenimagesfolder/images/'.$_GET['i'].'_'.$_GET['type'].'.'.$_GET['ext']);
} else {
    //not found
}
?>
0 голосов
/ 17 мая 2011

"mod_rewrite" - все попытки получить доступ к изображению через поддельный путь к файлу PHP с именем файла изображения в качестве параметра запроса, а затем выполнить свою магию там. Хранение изображений вне общей папки должно предотвращать нежелательный общий доступ. Либо сохраните фактическое изображение в самой БД.

...