我有一个简单的登录/访问控制系统来保护一些受限制的页面,但在这些页面内有一些需要保护的链接,即Word文档。因此,如果我将这些资源保留在 webroot 中,它们就可以通过 URL 访问。保护受限制页面内的这些资源的最佳方法是什么?我知道我可以用密码保护该文件夹,但用户会受到两次挑战,一次针对受限页面,另一次针对资源链接。有什么建议吗?
根据您的用例,您在这里有几个选项。
-
使用 PHP 提供文件服务。基本上,要么拦截 PHP 读取文件的所有尝试(使用 mod_rewrite 规则),要么直接链接到 PHP 并将文件放在文档根目录下。然后使用类似的东西fpassthru http://us.php.net/manual/en/function.fpassthru.php将文件发送到浏览器。请注意,您must正确设置内容类型标头。另请注意,这会占用大量服务器资源,因为服务器需要读取 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 提供文件服务时,它无法提供其他页面)以换取这种好处......
-
使用网络服务器发送文件,类似于X-SendFile http://blog.lighttpd.net/articles/2006/07/02/x-sendfile(Lighttpd),X-SendFile https://tn123.org/mod_xsendfile/(Apache2/2.2) 或X-Accel-Redirect http://wiki.nginx.org/XSendfile(NginX)。因此,您可以将对文件的所有请求重定向到 PHP(手动或重写)。在 PHP 中,您需要进行身份验证。您将发送 Content-Type 标头,然后发送类似的标头X-SendFile: /foo/file.doc
。服务器实际上会发送文件,所以你不必这样做(它是far比从本地 PHP 发送更高效)。
header('Content-Type: ...');
header('X-SendFile: /foo/file.doc');
die();
这里的主要好处是您不需要从 PHP 提供文件。您仍然可以执行您想要的所有身份验证和日志记录,但在开始传输文件后立即释放 PHP。
-
使用类似的东西mod_secdownload http://redmine.lighttpd.net/wiki/1/Docs%3aModSecDownload(lighttpd)或mod_auth_token http://code.google.com/p/mod-auth-token/(阿帕奇)。基本上,当您生成文件的链接时,您会在 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 http://www.edgecast.com/提供类似的功能,您可以设置一个令牌,该令牌在设定的时间后过期。如果您有的话,这个案例会很好用lot流量,并且可以证明 CDN 的费用是合理的。 (注意:与链接的 CDN 没有隶属关系,仅链接是因为我知道它们提供该功能)。
就我个人而言,我已经完成了上述所有操作。您的用例是什么确实很重要。如果您正在构建一个将安装在共享主机或您无法控制的多个不同服务器上的系统,请坚持使用第一个选项。如果您拥有完全控制权并且需要节省服务器资源,请执行其他两项之一。
Note:除了这三个之外还有其他选择。这些只是最容易实现的,大多数其他选项与这些选项足够相似,可以归入该类别......
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)