我有一个简单的登录/访问控制系统来保护一些受限制的页面,但在这些页面中有一些需要安全的链接,即Word文档。因此,如果我将这些资源保留在webroot中,则可以通过URL访问它们。保护受限页面内这些资源的最佳方法是什么。我知道我可以用密码保护文件夹,但用户将被挑战两次,一次用于受限页面,然后用于资源链接。有什么建议吗?
答案 0 :(得分:12)
根据您的使用情况,您可以在此处选择一些选项。
使用PHP来提供文件。基本上,要么拦截所有通过PHP读取文件的尝试(使用mod_rewrite规则),要么直接链接到PHP并将文件放在文档根目录下。然后使用类似fpassthru
的内容将文件发送到浏览器。请注意,必须正确设置内容类型标头。另请注意,由于服务器需要使用PHP读取整个文件并将其发送,因此会占用大量服务器资源,因此很容易,但不是很轻。
$f = fopen('file.doc', 'r');
if (!$f) {
//Tell User Can't Open File!
}
header('Content-Type: ...');
header('Content-Length: '.filesize('file.doc'));
fpassthru($f);
die();
这样做的主要好处是它简单易用(适用于所有服务器)。但是,您正在交换宝贵的服务器资源(因为虽然PHP正在为该文件提供服务,但它无法为另一个页面提供服务)...
使用Web服务器使用X-SendFile
(Lighttpd),X-SendFile
(Apache2 / 2.2)或X-Accel-Redirect
(NginX)等方式发送文件。因此,您将所有请求重定向到PHP(手动或重写)。在PHP中,您将进行身份验证。您将发送Content-Type标头,然后发送类似X-SendFile: /foo/file.doc
的标头。服务器实际上会发送文件,因此您不必(比远更有效率比从本机发送PHP更高效。)
header('Content-Type: ...');
header('X-SendFile: /foo/file.doc');
die();
这里的主要好处是您不需要从PHP提供文件。您仍然可以执行所需的所有身份验证和日志记录,但在开始传输文件后立即释放PHP。
使用类似mod_secdownload
(lighttpd)或mod_auth_token
(Apache)的内容。基本上,当您生成文件的链接时,您在PHP中创建一个令牌。此令牌是密码的MD5与当前时间戳的组合。这里的好处是URL仅对您在配置中指定的时间有效(默认为60秒)。这意味着你提供的链接只会激活60秒,然后任何进一步尝试查看内容都会产生400系列错误(我不是肯定的,这是我的头脑。)
$filename = '/file.doc';
$secret = 'your-configured-secret-string';
$time = dechex(time());
$token = md5($secret . $filename . $time);
$url = "/downloads/$token/$time$filename";
echo "<a href="$url">Click Here To Download</a>";
这样做的主要好处是与实现相关的开销很小。但是你必须习惯让URL在一段时间内有效(默认为60秒)......
将其推到CDN上进行处理。这类似于选项#3(上面的那个),但是使用CDN来处理文件服务而不是本地服务器。某些CDN(例如EdgeCast)提供了类似的功能,您可以设置在一段时间后过期的令牌。如果您拥有很多的流量并且可以证明CDN的费用是合理的,那么这种情况将很有效。 (注意:与链接的CDN没有任何关联,只有链接,因为我知道他们提供了这些功能)。
至于我个人如何做,我已经完成了上述所有工作。你的用例非常重要。如果您正在构建将要安装在共享主机或您无法控制的多个不同服务器上的系统,请坚持使用第一个选项。如果您具有完全控制权并需要节省服务器资源,请执行其他两个中的一个。
注意:除了这三个之外还有其他选项。这些只是最容易实现的,大多数其他选项都足够相似,以适应这个类别......
答案 1 :(得分:0)
我没有尝试使用word文档(仅限图片),但我会尝试直接从php see my answer about images提供文档。
它类似于a
标记链接到提供Word文档作为其内容类型的php页面。