tags:

views:

540

answers:

3

Because of safety (check if user are logged in), I call a php-document when showing images.

<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']));
}

...?>

When doing this, I hope the user never will know the direct url to the image, and when trying to show an image, the user has to be logged in.

I'm not sure this is the best way. Is there a more simpler/better way of doing this, and is this safe. When the script is echoing, it's a bit slow.

  • I want the image to be safe (only logged in user should have access to the image)
  • I want the image to be shown as fast as possible

Looking forward for all your expert-tips.

+4  A: 

Hi,

First of all, instead of reading the file with file_get_contents and, only then, echoing its content, you can use readfile : it will do both operations in one call -- which will probably be fastest and use less memory than :

  • load the full file in memory with file_get_only
  • and, only then, send that content to the outout


Then, if you only want identified to have access to the images, you don't have much of a choice : if you indentification mecanism is based on PHP, you'll have to pass by PHP to restrict access on the file -- which, yes, will be a bit slower than if using Apache directly to serve the content.


Also : here, you say :

I hope the user never will know the direct url to the image

Reading this, I suppose that your images can be accessed directly via Apache, bypassing your PHP script, if someone knows their URL ; security by obscurity is not good.

A better solution, if you don't want your images to be served by Apache would be to put them in a directory from where Apache will not serve anything :

  • either a sub-directory of your document-root, protected by a .htaccess file containing "Deny from all"
  • or a directory that is not under your document-root, and, so, will never be served by Apache.

Either way, this ensure only your scripts can access the files, and not Apache directly -- which means not a user bypassing the script.


Another idea, about the performance problem, might be to indicate the browser that it can cache your images -- at least, if that makes a sense.

For instance, you might be interested by HTTP-headers suchs as "Etag" and/or "Last-Modified".

Pascal MARTIN
Which operation is the fastest?
Johan
@Johan : hi, I've edited my answer to add a couple more informations ; hope this help :-)
Pascal MARTIN
@Pascal MARTIN thanks a lot
Johan
@Johan > you're welcome :-)
Pascal MARTIN
About caching images, I was recommended not to, see this answer: http://stackoverflow.com/questions/1385964/how-to-get-the-browser-to-cache-images-with-php/1386091#1386091
Johan
Oh, I see the point that's talked about there -- in that case, I would probably decide to cache or not depending on whether or not the images are used often, and the load of the server -- and not use a too long time, I suppose... alse depends on the "level of secret" you want.
Pascal MARTIN
A: 

Since you require that only logged in users view the image then I would say that you don't really have a choice when it comes to this. You will have to keep doing it like this until your site becomes insanely popular at which point you might be able to figure out a more efficient system for multiple servers using a lower-level access check than PHP (which costs a lot).

<?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']));
}
Xeoncross
A: 

Pascal MARTIN is correct that readfile is essentially the same as echo and file_get_contents. I doubt there is any significant difference in performance, but it's clearer to use readfile.

As far as only allowing logged in users to see the images, put the images outside of your web-directory. Using readfile, you can grab the file from some other directory. That way, there's no way they could access it, even if they did guess the url.

notJim