tags:

views:

24

answers:

2

I am creating an online service where "special users" can upload their images. It is very important that the images are not exposed to anyone else than the user who uploaded them. I have heard that the best way to protect the images is to put them over the webscope.

So far so good.

My problem is that i can't display the images, how is this done? The application is written in PHP and the directory structure is like this:

    /                    # this is where i placed the images
    /www
    /www/domain.com/     # This is the root of the website

I have put up a testscript to retrieve the images with this code

    header('Content-type: image/jpeg');
    $image = imagecreatefromjpeg( realpath('../../image.jpg'));
    imagejpeg($image);
    imagedestroy($image);

which delivers the image to this file which displays it

    <img src="retrieve-image.php" />

Can anyone please tell me what I am doing wrong? Can it be the php.ini which is set incorrectly? Is there a more easy way to protect the images?

Thanks in advance !!

// Mathias Bak

P.S. How do i write code in my post the proper way??

A: 

Why don't you use a login mechanism to verify if a person is allowed to access the image? This is easily done and security is high.

Thariama
I have a login mechanism, but if somebody just enters "http://domain.com/path/to/image/image.jpg", it will be shown wether he is logged in or not. Thats my concern...
Mathias Bak
In that case you need to store the images in a database instead of just having the images liing around in your webspace. Let the php script access the image from the database only if they are allowed to.
Thariama
Thanks for the quick response!!I could do that, but db-traffic is to expensive for the volume I am going to use, so that's unfortunately not an option.
Mathias Bak
how big in size will your images be?
Thariama
They will be about 3 - 4 mb each. Size of the (full) images is estimated to allocate 50 Gb diskspace each year. And traffic will be increasing proportionally each year too.
Mathias Bak
A: 

You're going about retrieving the image wrong. There's no reason you should decode the JPEG into a raw bitmap in memory (imagecreatefromjpeg(), which can suck a HUGE amount of memory if the original image is largeish), re-compress it (imagejpeg() with all the lossiness and CPU overhead that goes along with it), when all you need to do is copy the bytes over.

Assuming you want the capability of multiple images being uploaded for multiple different users, you'd need some way of identifying which image the user wants, which can be done easiest by recording the uploads in a database and assigning a unique ID to each. There's lots of other answers on SO here how to do that, so I'm not going to hash it over again.

Your viewing script would have something like this:

<img src="retrieve-image.php?imageID=123" />

And retrieve-image.php would look like:

<?php

function is_user_allowed_to_see($imageID) {
   // figure out if user is allowed to see the specified image
}

if (is_user_allowed_to_see_this($_GET['imageID'])) {
    readfile("/www/uploads/domain.com/" . $_GET['imageID']);
} else {
    readfile("/www/domain.com/sorry-not-allowed.jpg");
}

readfile() is the preferred way of streaming a file to the user via PHP. It'll take care of reading the file's contents and sending it to the browser in chunks that won't exceed the script's memory limit.

Since you're loading the image data directly into an <img> tag, you can't output a plaintext "sorry, not allowed to see this" text, as it'd be an invalid image and you'll just get the broken picture icon. So, if the user's not allowed, send an image that contains text/image (say, a red slashed-circle) saying so instead of the actual image.

Marc B
Thanks for your answer and for the readfile() code. But it still does not work :( When i output $_SERVER['DOCUMENT_ROOT']; it prints **/home/www/domain.com/**. I have put the image in the the "home" folder which is over webscope.I wrote readfile( realpath("../../image.jpg" )); but that does not show any image. Any other suggestions?P.S. I would rank you up if i could, but i don't have enough points
Mathias Bak