保护文件不被直接访问

时间:2017-01-14 04:22:02

标签: php apache .htaccess mod-rewrite url-rewriting

我有一个保存文件的文件夹。可以从网页访问这些文件。假设该目录与manual/fileName.pdf类似。

我还有一个页面显示manual/文件夹中存储文件的列表,此页面受使用用户会话保护。因此,您必须先登录才能访问该页面。

我通过在文件夹中放置.htaccess来阅读,我可以阻止用户直接访问文件。但现在我甚至无法从该列表页面访问它们。

我在.htaccess写道:

RewriteEngine on
RewriteRule .documentation.php

这是我的文件列表脚本:

if ($handle = opendir('manual')) {
   while (false !== ($entry = readdir($handle))) {
     if ($entry != "." && $entry != "..") {
        if (!preg_match('/.php/', $entry) && !preg_match('/.htaccess/', $entry)) //prevent some file to be shown
            {echo "<a href='manual/$entry' target='_blank'>$entry</a><hr>";}
         }
     }
     closedir($handle);
}

知道如何访问文件吗?

1 个答案:

答案 0 :(得分:3)

通常,从文档根目录中提供受保护的文件不是一个好主意。特别是,当用户需要登录才能查看/访问它们。当您将服务委托给Web服务器时,您将无法以编程方式检查用户是否已登录,因为Apache Web服务器无法知道用户是否在PHP应用程序中进行了身份验证。一旦用户知道文件URL,她就可以访问该文件而无需登录系统。

有一个解决方法,我会帮你解决。但我强烈建议您将文件放在webroot之外,并开发一个脚本以便在访问时提供它们。这样,您可以在提供文件时检查经过身份验证和授权的会话。

但是,如果你坚持这样做,那就有一个解决方法。让我们布置一个示例目录结构:

/path/to/web/document/root
├── manual
│   └── .htaccess
│   └── file1.pdf  # protected
│   └── file2.pdf  # protected
│   └── file3.epub # protected
├── documentation.php
├── listing.php    # protected
└── .htaccess

您希望manual/目录中的文件受到保护,并且只有在用户登录时才能访问。因此,您将以下指令放在manual/.htaccess文件中:

RewriteEngine on
RewriteRule ^ /documentation.php [R]
# Your own rewrite rule has a syntax error and 
# causes a 500 internal error

这将重定向所有请求到父目录中的documentation.php文件。如果您不需要外部重定向,请删除R标记。

正如您所说,现在问题是对manual/内的文件的任何请求都会被重定向到文档文件。

解决方法是检查HTTP_REFERER标头并确保请求来自listing.php文件。

RewriteEngine on

# Feel free to change example.com with your own domain    
RewriteCond %{HTTP_REFERER} !^http://www.example.com/listing.php$
RewriteRule ^ /documentation.php [R]

这样,对manual/file2.pdf的任何直接请求都会导致重定向到documentation.php,但如果用户点击listing.php中的链接,则可以毫无问题地访问该文件。< / p>

如果您需要使引用条件更通用,请参阅此文章:
Referrer Checking with .htaccess

警告that a user can easily spoof the HTTP_REFERER header,从而无需登录即可访问文件。实现这一目标的唯一真正的防弹方式是我在本文开头所说的。

您可能还想使用基本的http身份验证来保护manual/目录。但是这样,用户需要输入另一个用户名/密码组合才能访问该文件夹。