使用PHP限制对登录用户的内容访问

时间:2010-02-12 00:53:51

标签: php mysql apache authentication session

我有LAMP设置,我只是希望能够保护网页上的内容(图像,CSS,视频等),以便只有登录的用户才能访问它。

我意识到我可以使用.htaccess轻松完成这项工作。但是我不想使用身份验证弹出窗口,我希望能够使用会话并且能够注销。

我正在使用php来完成使用mysql进行身份验证并创建会话。这非常有效。但仍然可以访问图像,CSS,JavaScript等。

如果存在有效的php会话,我如何才允许访问内容?

我遇到过使用mod_rewrite将文件转发到php文件(比如auth.php?file = ...)并在那里进行会话检查。对于已经检查过的页面中的每个图像,检查会话似乎效率低下。这似乎是一个黑客,我一直认为有一个更清洁的方式来做到这一点。

是否有像mod_session_cookie这样的apache的mod可以检查我的会话数据库中是否存在具有会话密钥的cookie,如果是,则为目录设置Allow all?

或者,是否可以使用mod_auth_mysql,但也可以使用php表单而不是身份验证弹出窗口使用会话和登录?

修改

以下是我解决问题的方法:

在我的apache配置文件(不是.htaccess)中,我添加了:

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>

脚本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);
?>

这就像一个魅力。使用这个和session_set_save_handler我能够使用mysql支持的php会话来保护php页面和其中的所有内容。我希望有人觉得这很有用。

一些警告:

  • 如果要在虚拟主机内部使用,则需要在虚拟主机块内定义RewriteMap语句。将它放在块外面是行不通的。
  • 您必须在定义RewriteMap之前设置RewriteEngine,否则将被忽略。
  • RewriteLock不能位于虚拟主机块中。
  • 与任何shell脚本一样,php文件必须由apache用户执行,并且没有^ M的
  • RewriteMap语句不能放在.htaccess中,但使用该地图的其他语句可以。

3 个答案:

答案 0 :(得分:6)

RewriteCond %{HTTP_COOKIE} !mysessioncookie=([^;]+)
RewriteRule .+\.(jpg|css|js) forbidden.html [R=403]

答案 1 :(得分:0)

不是直接链接到资源,而是使用某种形式的控制器来提供图像。

例如,链接到'images / bob.jpg'实际上并不指向资源,而是指向登录的脚本,如果成功,则发送带有正确数据的图像/ jpeg标题。

答案 2 :(得分:0)

我实际上不使用Apache;我使用lighttpd,其中包含一个插件,您可以使用该插件根据URI中是否传递正确的哈希来限制对文件夹的访问。基本上,您的应用程序逻辑和Web服务器共享一个秘密盐,然后用于生成当前时间的哈希值,该哈希值也随哈希值传递。如果时间在过去5分钟内,则授予访问权限。如果没有,或者哈希是无效的,那么它就不是。我正在谷歌上搜索目前是否有类似的Apache插件。

编辑:mod_auth_token似乎对Apache做了同样的事情。