Drongo_III Posted January 11, 2015 Share Posted January 11, 2015 Hi Guys I'm building a php application where users must login to access a set of private images. The images display as a set of thumbs to the user, which they can click to download the full size image. so I need to read a whole batch images (500+) of them from a directory. So I'd like some advice on the best way to: 1) Keep files from being world readable.I know you could probably achieve this using htaccess or storing them outside the document root but which is best given that I need to read a whole directory with hundreds of images? 2) How to access the images If it turns out storing the images off document root is the way to go, what's the most efficient way to read a directory off the doc root and access the individual images (readfile for instance)? Thanks in advance, Drongo Quote Link to comment Share on other sites More sharing options...
Frank_b Posted January 11, 2015 Share Posted January 11, 2015 (edited) 1. store the images outside your documentroot. 2. Use sessions to remember who may download and who doesn't 3. Use a PHP script to download the images: get_image.php: <?php if(!isset($_GET['filename'])) { header("HTTP/1.0 404 Not Found"); echo 'no filename received!'; exit; } session_start(); if(!isset($_SESSION['may_download']) || (isset($_SESSION['may_download']) && $_SESSION['may_download'] === FALSE)) { header('HTTP/1.0 401 Unauthorized'); echo 'This content is not available for you.'; exit; } $path = '/var/www/private/images/' . $_GET['filename']; if(!file_exists($path)) { header("HTTP/1.0 404 Not Found"); echo 'filename does not exist!'; exit; } // output the image header("Content-Type: image/jpg"); header("Content-Length: ". filesize($path)); header("Content-Disposition: attachment; filename=". $_GET['filename']); echo file_get_contents($path); ?> To download an image: http://yourdomain.com/get_image.php?filename=picture1.jpg To show the image in a HTML page: <!DOCTYPE html> <html> <head> <title>something</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <div><img src="get_image.php?filename=picture1.jpg" alt="picture1" /></div> </body> </html> Edited January 11, 2015 by Frank_b Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted January 11, 2015 Share Posted January 11, 2015 There are two possible approaches: You keep the files within the document root, but you randomize the filenames (and of course turn off any directory listing). If the random numbers are sufficiently strong, it's impossible to find an image until your PHP scripts hands out the filename. You keep the files outside of the document root and make them accessible through a PHP script which checks the permissions on each request. Both approaches have advantages and disadvantages. The first one is by far the easiest and most efficient approach, but it's somewhat fragile, and you can't have fine-grained access management: Once the filename is known, it's known. You cannot revoke the permission. On the other hand, anybody who had the permission once might as well save the image, so that's not really a big difference. The second approach is more robust, because all requests will go through the PHP script. You can grant and, theoretically, revoke access at any time. But of course you'll have the overhead of running PHP on every request. Both approaches can be optimized with the “sendfile” mechanism: Instead of literally reading the file with PHP and sending the whole content to the webserver which in turn sends it to the client, you just tell the webserver to serve the file. Quote Link to comment Share on other sites More sharing options...
Drongo_III Posted January 11, 2015 Author Share Posted January 11, 2015 Thanks Guys Both of those answers are super helpful! I will give some thought and figure on which approach best suits. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.