Reputation: 45
I have a LAMP setup and I just want to be able to protect content on the webpage (images,css,videos,etc) so that only logged in users can access it.
I realize I can do this easily with .htaccess. However I do not want to use the authentication popup, and I want to be able to use sessions and also be able to logout.
I am using php to do the job of authenticating with mysql and create sessions. This works great. But images, css, javascript etc are still accessible.
How do I allow access to the content only if a valid php session exists?
I have come across using mod_rewrite to forward files to a php file (like auth.php?file=...) and do session checking there. This seems inefficient to check the session for every single image in a page that has already been checked. It seems like a hack and I keep thinking there is a cleaner way of doing this.
Is there a mod for apache like mod_session_cookie that could check if a cookie with a session key exists in my session database and if so sets Allow from all for the directory?
Alternatively, is it possible to use mod_auth_mysql but also be able to use sessions and login using a php form and not the authentication popup?
EDIT:
Here is my solution to the problem:
In my apache configuration file (not .htaccess) I added:
RewriteLock /var/www/lib/rewrite.lock
<VirtualHost>
#...
RewriteEngine on
RewriteMap sessionValid prg:/var/www/lib/allow.php
<Directory /var/www/client/*>
RewriteEngine on
RewriteCond %{HTTP_COOKIE} !client-cookie=([^;]+)
RewriteRule .* - [L,R=403]
RewriteCond %{HTTP_COOKIE} client-cookie=([^;]+)
RewriteCond ${sessionValid:%1} !valid
RewriteRule .* - [L,R=403]
</Directory>
</VirtualHost>
And the script allow.php:
#!/usr/bin/php5
<?php
set_time_limit(0);
echo "";
$stdin = fopen("php://stdin","r");
$db = mysql_connect(...);
mysql_select_db(..., $db);
$querypre = "SELECT ID FROM Sessions WHERE ID='";
while (1) {
$line = trim(fgets($stdin));
$query = $querypre.mysql_real_escape_string($line)."'";
$result = mysql_query($query);
if (mysql_num_rows($result) > 0)
echo("valid\n");
else
echo("0\n");
}
mysql_close($db);
?>
This works like a charm. Using this and session_set_save_handler I was able to use php sessions backed by mysql to secure both the php pages and all content within. I hope someone finds this useful.
Some caveats:
Upvotes: 8
Views: 5153
Reputation: 5803
I actually don't use Apache; I use lighttpd, which includes a plug-in that you can use to restrict access to a folder based on if a correct hash is passed in the URI. Basically, your application logic and the webserver share a secret salt that is then used to generate a hash with the current time, which is also passed with the hash. If the time is within the past 5 minutes, then it grants access. If not, or if the hash is invalid, then it doesn't. I'm googling around to see if there's a similar plugin for Apache at the moment.
Edit: mod_auth_token appears to do the same thing for Apache.
Upvotes: 1
Reputation: 798606
RewriteCond %{HTTP_COOKIE} !mysessioncookie=([^;]+)
RewriteRule .+\.(jpg|css|js) forbidden.html [R=403]
Upvotes: 5
Reputation: 490203
Instead of linking straight to the resources, use some form of controller to serve the images.
For example, linking to 'images/bob.jpg' wouldn't actually point to a resource, but a script, which checks login, and if successful, sends image/jpeg headers with the correct data.
Upvotes: 0