View Access: show images on website but block direct access to images

5,449 views
Skip to first unread message

mirjam k

unread,
Oct 13, 2011, 8:21:44 AM10/13/11
to joomla-de...@googlegroups.com
Hello,

I'm working on a gallery component for which I'm implementing View Access. Now that I've set it up I wondered what to do with users who I don't want to be able to see certain images (e.g. non-registered users who are not allowed to see images in a gallery for registered users), but who are able to download it once they know the image name and where it's stored. E.g. the smart ones who can read the source code, see where images are stored and find out an image file name: they can piece together the direct downloadlink. And I'd like to block them... if possible.

Is it possible to set it up that users knowing the direct link are not allowed to view/download an image that way, but users with the proper View Access surfing on the site, can see the galleries that they are allowed to see in Joomla and are able to download the images?

On the web, I found that you can use an .htaccess file with the line "deny from all" that you can put in a specific directory, e.g. the directory with the images: users then have no direct access to the files in that directory. So I've tried it, and then none of my images are shown...

I've also looked at a couple of gallery/download extensions available in the JED (searching for examples), but the ones I checked don't block direct access.

With kind regards,
Mirjam

Nicholas K. Dionysopoulos

unread,
Oct 13, 2011, 8:32:11 AM10/13/11
to joomla-de...@googlegroups.com
Hi Mirjam,

the first and most obvious way to do that is to make the filename hard to use. This can be accomplished my "mangling" the filename of the images. During upload, use the MD5 hash of the uploaded file's name plus another string (e.g. the site's secret key which is defined in configuration.php) to create a hard to guess filename. The chance of someone guessing the correct filename is a little less than one in 4 billion. However, if someone gives them the filename or the URL, they will still be able to see the image. Considering how good Google is indexing images, I guess that solution won't hold much water.

The other approach is, like you said, using a .htaccess to protect the images directory. Of course, this means that nobody can access them. How do you allow authorised users to access them? Simple! Use a view in your component which "channels" the image data to the browser. The idea is that the src attribute of the image tag points to a Joomla! URL like index.php?option=com_yourcomponent&view=image&id=1234&format=raw. In the controller's display() method for that view, check the ACLs and if they allow showing images just read the corresponding file and push it to the browser. You may have to also send the HTTP headers with the correct MIME type. After that, just use JFactory::getApplication()->close(); to terminate Joomla!'s execution and you're ready. Take a look at how file downloads are implemented in any download component (e.g. DOCman or Akeeba Release System) for more ideas towards this implementation.

Cheers,

Nicholas K. Dionysopoulos
Web Development & IT Services
http://www.dionysopoulos.me



--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To post to this group, send an email to joomla-de...@googlegroups.com.
To unsubscribe from this group, send email to joomla-dev-gene...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/joomla-dev-general?hl=en-GB.

garyamort

unread,
Oct 13, 2011, 9:45:42 AM10/13/11
to joomla-de...@googlegroups.com


On Thursday, October 13, 2011 8:21:44 AM UTC-4, Mirjam wrote:
Hello,

I'm working on a gallery component for which I'm implementing View Access. Now that I've set it up I wondered what to do with users who I don't want to be able to see certain images (e.g. non-registered users who are not allowed to see images in a gallery for registered users), but who are able to download it once they know the image name and where it's stored. E.g. the smart ones who can read the source code, see where images are stored and find out an image file name: they can piece together the direct downloadlink. And I'd like to block them... if possible.

Is it possible to set it up that users knowing the direct link are not allowed to view/download an image that way, but users with the proper View Access surfing on the site, can see the galleries that they are allowed to see in Joomla and are able to download the images?


One method of doing so is to store the files someplace inaccessible to the web server.  For an apache web server, you can add an htaccess file as you discovered.  You can also store the files outside the web directory entirely, such as if your web directory is /home/username/public_html store the files in /home/username/gallery

When you use this method, it means that to view an image it must be loaded through your component, your component can do a readfile() to load the file and send it to the browser for authorized users.


The downside of this method is that using php to display images is an order of magnitude slower than direct web access.  For service static image files, LightHTTP has been shown to process them much much faster.  It also has the ability to protect the files with a "secret" dynamic url, see http://redmine.lighttpd.net/wiki/1/Docs:ModSecDownload for details.   Basically, when you generate the image url, you use a shared secret to timestamp the url, and lighty will only allow access to the file if the timestamp matches[this also means that the url constantly changes and old urls cannot be used]


There are also version of this module/functionality for other web servers. For apache:

And for nginx there is something slightly similar:

For a mix of speed and stability, you can use redirects in combination with tokens.  So, for example, to view an image the url is:

To break down the url:
gallery - the SEF friendly mapping to your gallery component
album1 - the name of the album
cake-and-eat-it.jp - the name of the image
tmpl=component - this parameter tells joomla to use the "component.php" template file instead of the index.php file.  This template file just displays the component and no modules, so it is lighter and faster.

Now, in your code you lookup the access of the image vs the user's rights.  If they have access rights, then you generate the token and redirect the browser, say to http://www.mydomain.com/SECRETTOKEN/media/gallery/album1/image.jpg
If they do not have access rights, then you can use this opportunity to display an error message and cross-sell, such as:
"This image is for subscribers only, please login or subscribe today" 

Personally, I'd recommend the redirect method with a secret token.  For servers that do not support the generation of tokens, you can code your own solution in PHP using readfile and verify the token.  
The benefit of this is threefold:
1) Images have static url's and the redirects help get to the actual image
2) Servers that support token generation get a speed bump
3) Most CDN's also support token secured files, so your app can be extended later to store files in Amazon S3 or a similar service.


This url will call your gallery component


 

mirjam k

unread,
Oct 15, 2011, 6:43:25 AM10/15/11
to joomla-de...@googlegroups.com
Thanks Nicholas and Garyamort for your help and information.

I will study how Akeeba Release System works in this respect, and I just read that Phoca Gallery let's you use a directory outside of the webdirectory, they have a 'warning' for the user (found here: http://www.phoca.cz/documents/17-phoca-download-component/366-access-rights). Also, Akeeba Backup has this kind of information: https://www.akeebabackup.com/documentation/akeeba-backup-documentation/securing-temp-output-directories.html. Funny how you can find things once you know what to look for...  I have enough points to start learning from now.

By the way, I really like this list: questions, however small or big, easy or complicated, are answered in a nice way by many different people.

With kind regards,
Mirjam

Nicholas K. Dionysopoulos

unread,
Oct 15, 2011, 6:45:04 AM10/15/11
to joomla-de...@googlegroups.com
You're welcome! We're a helpful bunch and we all love to see other people learning how to become successful Joomla! developers :)

-- 
Nicholas K. Dionysopoulos
Lead Developer, AkeebaBackup.com
--

Andy Nagai

unread,
Oct 16, 2011, 1:01:40 AM10/16/11
to joomla-de...@googlegroups.com
Google can index a gallery or image page that requires a login? Just
hash or encrypt the filename. I would think that if you had a gallery
page of like 20 thumbnail images or so and running those images
through a component would be much slower then direct.
Reply all
Reply to author
Forward
0 new messages