• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Restrict direct image viewing

#1
[eluser]Chris Williams[/eluser]
I'm not sure how to approach this. Maybe I can get some pointers/resources to help me with this.

Okay, I don't want images viewable from where they get uploaded to the site.

Code:
<img src="/upload/2008/06/05/10.png" />

because this photo was marked private and associated to a db record, I'd LOVE to be able to refer to it as this

Code:
<img src="/user/a.png" />

"user" is a field value and "a" is another field value.

#2
[eluser]sikkle[/eluser]
Don't be surprise that you can call a controller to show picture, so you can never call the right name and add security layer.

good luck!

#3
[eluser]Eric Cope[/eluser]
If I understand you correctly, you want to prevent images from being publicly accessible in certain directories. You could use .htaccess to control that.

You could also store the image in the database, however, I am not sure of the performance hit on that (I don't do it that way).

#4
[eluser]Lone[/eluser]
From what I can gather there are two issues you need to resolve.

1. Protect the directory they are actually in - just use a htaccess file like suggested above.

2. Output the images from a different path

For the second solution there are a few ways you achieve it depending on how strong you want to hide the images. You could save a reference to each image in the DB with a unique token eg:

Code:
ID  | file     | token
----+----------+--------------------
3   | 5353.png | gj346dagfaw4653dfd
------------------------------------
4   | 2563.png | hadfg346dafshdfhsa
------------------------------------


Create a controller called 'image' with a method called 'view' which you would have the following:

Code:
function view() {
  $token = $this->uri->segment(3);
  $path = $this->Somemodel->get_image_path($token);
  $mimetype = get_mimetype($path); // will need file_helper loaded
  ob_get_clean();
  header('Content-Type: '.$mimetype);
  ob_flush();
}

Then for people to access the image you would set a source as follows:
Code:
<img src="image/view/&lt;?=$token; ?&gt;" alt="image" />

#5
[eluser]Bramme[/eluser]
Is it possible to store your images outside your webroot? so instead off say /httpdocs/images/, say /private/images/ or so? That wouldn't cause the need to protect your directory with a .htaccess... Though it' might be easier that way.

#6
[eluser]Chris Williams[/eluser]
Hey Lone!

Thanks for the input.

I didn't see any get_mimetype function in the user guide, but I don't think it makes a difference either way. If I hard code the actual address instead of looking it up in the db, I'm not getting it to display anything.

Code:
$path = '/secret_directory/this_image.png';
        
$mimetype = get_mime_by_extension($path); // will need file_helper loaded
ob_get_clean();
header('Content-Type: '.$mimetype);
ob_flush();

So when I call it from /index.php/index/view by itself, Firefox tells me it contains errors. I'm a little too novice to tell what's not working.

#7
[eluser]Chris Williams[/eluser]
Okay, here's where I'm at right now. This will work:

Code:
function view()
{
    //get actual file for testing the code
    $path = 'http://127.0.0.1/secret/2008/06/05/img_11.png';
    
    $mimetype = get_mime_by_extension($path); // will need file_helper loaded
    header("Content-Type: ".$mimetype);
    $img = imagecreatefrompng($path);
    imagepng($img);
    imagedestroy($img);
}

but it will fail is I set the .htaccess file to deny:
Code:
order deny,allow
deny from all

Is there a way for my php to load the image while denying access for everyone else?

#8
[eluser]Seppo[/eluser]
Hey, a small comment, the view method is reserved for php 4 so watch out that...

On the other side, you should use a file path - not an url path.
And you don't really need the gd library functions.
Code:
$path = BASEPATH . '../secret/2008/06/05/img_11.png'; // Correct the path if necesary but it has to be a local path
$mimetype = get_mime_by_extension($path); // will need file_helper loaded
header("Content-Type: ".$mimetype);
readfile($path);

#9
[eluser]Chris Williams[/eluser]
[quote author="Seppo" date="1212902295"]Hey, a small comment, the view method is reserved for php 4 so watch out that...

On the other side, you should use a file path - not an url path.
And you don't really need the gd library functions.
[/quote]

Thank you so much for the tip. It worked perfectly.

#10
[eluser]Daniel Eriksson[/eluser]
If you want to access-control your images I suggest:

* Store the images in a protected directory (outside webroot for example).
* Store information about each image in a database (original file name, MIME-type, size, access restrictions, ...).
* In your image controller, check if the current user is allowed to view the image.
* Use header() and readfile() to send the image to the user.

Take a look at my reply in another thread: http://ellislab.com/forums/viewthread/75997/#380686


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.