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:
- The RewriteMap statement needs to be defined inside the virtual host block if you are going to use it inside that virtual host. Placing it outside of the block will not work.
- You must have set RewriteEngine on before defining the RewriteMap or it will be ignored.
- RewriteLock cannot be in the virtual host block.
- As with any shell script, the php file must be executable by the apache user and void of ^M's
- RewriteMap statements cannot be placed in .htaccess but the other statements that use the map can.