Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Control access to files based on DB values with PHP/Apache

What i want

I'm making a system where, when a user uploads an image it goes to the folder images, where there is two copies of the image, a thumb and a bigger one.

Now, when a user uploads an image it's done alongside insertion of a row in a MySQL database, where the image gets an id, and the row holds a value that determines if the images is available to the public or not (1 for only thumb available, 2 for both) along with the owner(admin) of the image.

What i wan't to do is, if a user tries to reach the image by going to the image's URL, and the value in the database says that it should not be publicly available, and the session of that user is not the owner of the image, (admin not logged in) it should either say image not found or access denied.

What i imagine

If it could be done with php i imagine something like this:

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

I could maybe hide the images in a .htaccess protected folder, make a imgae_get.php that accepts URL variables, sees if the image is available, and loads the image if so. I just want to avoid having to de/re-compile the image and other server power consuming processes.

My question is, can i control the image like this? Is there a way to make a php script appear as an image it loads internally? Or is there maybe some other/better way than through PHP? (Apache maybe?) Any suggestions is much appreciated.

like image 895
Kristoffer la Cour Avatar asked May 17 '11 12:05

Kristoffer la Cour


2 Answers

//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");
like image 148
Explosion Pills Avatar answered Sep 30 '22 13:09

Explosion Pills


You can redirect all requests for certain filetypes (or filenames, anything you can regex) with an '.htaccess' file in your 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]

You can determine the original request from the $_SERVER superglobal, and use the appropriate headers to alert the browser you're returning an image. Then you read the image from disk (with file_get_contents() or similar) and write it to the browser with echo, in the same way you'd output HTML.

like image 39
Andy Avatar answered Sep 30 '22 13:09

Andy