Hi
I’ve got a project whereby I need to restrict access to a folder of image files based on the login status of EE (i.e. only logged in members get access).
One option is to store files outside of the web root and direct all requests to an EE Module which checks the the login status as normal. If authentication checks out, serve the image by sending a header and then the contents of the file. So an image src would be something like:
/?ACT=99&image=/path/to/image.jpg
That will work fine, I’ve done similar things before, but I’m not really happy with it as a solution. Ideally, the images would be stored inside the web root and Apache would take care of the authentication directly without needing to start up EE or send the contents of the file through a PHP script.
To do that we’re going to need to get Apache to recognise the current EE user session, or at least give it some other way to know if a request is legal. As Apache wizardy is a bit of a gap in my knowledge, I’m not sure if this is even possible.
Any ideas?
I don’t think there’s any way to authenticate without initializing EE or your own custom PHP, as you’ll need to cross-check cookies with the database. But there is an alternative to loading the contents of the file into memory and then serving via PHP: mod_xsendfile. After you authenticate the user, all you have to do is send the right headers to tell apache to serve up the file directly. Here’s a tut I just googled: http://elivz.com/blog/single/mod_xsendfile/
To answer the question of apache restricting access on php-based authentication, then unfortunately this isnt possible as apache auth mechanism kicks in before any php is loaded for each request (you would need to trigger a separate apache http auth request, which would require the user to login in twice effectively).
An alternate solution to the above would be to implement a mod_rewrite setup (ie no apache modules needed).
The trick would be rewrite any urls for static files to parse through a php script instead, and then the php script could authenticate and then output the file.
The benefit here is that you wouldnt need to set different headers, or change the urls for the original images etc in your web pages. The php script could also be standalone from EE (reducing overhead) and assuming the EE auth used is session based, you can just have a simple session check (if not, then this is easy to fix).
The downside however is that you would be loading php scripts for images, which is obviously an overhead (although not much as you may think as apache always initialises php even for static file requests).
mod_xsendfile is so nearly, almost there. For file downloads it’s perfect, I can do my native application authentication and then let Apache deal with the nasty business of file serving. Simple as this:
if($is_authorised) {
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("X-Sendfile: $path");
} else {
show_an_error_message();
}
Nice. What is not quite happening is inline images. echo get_file_contents($path) produces a nice image inside an IMG tag, whereas header(“X-Sendfile: $path”) without the content-disposition header produces nothing.
I’m hoping I’m just missing a header or two, or maybe it’s because I’m on my Win7 dev machine and I need to try it on a “real” server. Or maybe the mod was never intended for inline images. Frustratingly close …
p.s. Welcome to the forums Mr Dixon!
Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.