本文介绍了安全文件用PHP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的登录/门禁系统,以确保一些受限制的网页,但这些网页中有需要是安全的环节,即Word文档。因此,如果我把他们可以通过URL访问根目录内这些资源。这是为了保障这些资源是受限制的页内,最好的方法。我知道我可以设置密码保护的文件夹,但随后用户将受到挑战两次,一个是受限页面,然后将资源链接。有什么建议?

I have a simple login / access control system to secure some restricted pages, but within these pages there are links that need to be secure, i.e. Word documents. Therefore if I keep these resources within the webroot they could accessible via a URL. What is the best method to secure these resources that are within the restricted page. I know I could password protect the folder but the user would then be challenged twice, one for the restricted page and then for the resource link. Any advice ?

推荐答案

您有几个选择这里,这取决于你的使用情况。

You have a few options here, depending on your use-case.


  1. 使用PHP来提供服务的文件。基本上,无论是拦截所有企图读取PHP文件(使用mod_rewrite的规则),或直接链接到PHP,并把文档根目录下面的文件(S)。然后使用类似送文件到浏览器。请注意,您必须设置正确的内容类型标头。还要注意,由于服务器需要读取整个文件在PHP,并将其发送这会耗费大量的服务器资源,所以它很容易,但不轻。

  1. Use PHP to serve the file. Basically, either intercept all attempts to read the file by PHP (using a mod_rewrite rule), or link directly to PHP and put the file(s) below the document root. Then use something like fpassthru to send the file to the browser. Note that you must properly set the content-type headers. Also note that this will eat up a lot of server resources since the server needs to read the entire file in PHP and send it, so it's easy, but not light.

$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而正在服刑的文件,它不能提供另一页)为利益...

The main benefit to doing it this way is that it's easy and portable (will work on all servers). But you're trading off valuable server resources (since while PHP is serving the file, it can't be serving another page) for that benefit...

使用的网络服务器发送使用类似(lighttpd的),(的Apache2 / 2.2)或(Nginx的)。所以你的文件的所有请求重定向到PHP(手动或重写)。在PHP你会做您的身份验证。请发送的Content-Type头,然后发送类似一个头的X SENDFILE:/foo/file.doc 。服务器将实际发送文件,所以你不必(它的效率比从PHP发送本机)。

Use the web-server to send the file using something like X-SendFile (Lighttpd), X-SendFile (Apache2/2.2) or X-Accel-Redirect (NginX). So you'd redirect all requests to the file to PHP (either manually or rewrite). In PHP you'd do your authentication. You'd send the Content-Type headers, and then send a header like X-SendFile: /foo/file.doc. The server will actually send the file, so you don't have to (it's far more efficient than sending from PHP natively).

header('Content-Type: ...');
header('X-SendFile: /foo/file.doc');
die();

这里的主要好处是,你不需要从PHP服务文件。你仍然可以做你的认证和登录,你想的,但是释放PHP只要你开始传输文件。

The main benefit here is that you don't need to serve the file from PHP. You can still do all of your authentication and logging that you'd like, but free up PHP as soon as you start transferring the file.

使用类似 mod_secdownload (lighttpd的)或 mod_auth_token (阿帕奇)。基本上,你在PHP中创建一个令牌时生成的链接文件。该令牌是一个秘密的密码与当前时间戳组合的MD5的组合。这里的好处,就是网址只适用于您在配置中指定的时间(缺省为60秒)。因此,这意味着你给出来的链接才有效60秒,然后任何进一步尝试看到的内容将产生400系列错误(我还不能肯定它把我的头顶部)。

Use something like mod_secdownload (lighttpd) or mod_auth_token (Apache). Basically, you create a token in PHP when you generate the link to the file. This token is a combination of a MD5 of a secret password combined with the current timestamp. The benefit here, is the URL is only valid for how long you specify in the configuration (60 seconds by default). So that means that the link you give out will only be active for 60 seconds, and then any further attempts to see the content will generate a 400 series error (I'm not positive which off the top of my head).

$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>";

在做这种方式的主要优点是,有与实施相关的开销非常小。但你必须要熟悉其网址是有效的一组每次只(缺省为60秒)...

The main benefit to doing it this way is that there is very little overhead associated with the implementation. But you have to be comfortable with having URLs being valid for a set time only (60 seconds by default)...

推它关闭到一个CDN来处理。这就好比选项#3(上面的),但使用CDN来处理,而不是服务于本地服务器的文件。有些的CDN如 EdgeCast 为你设置这一个设定的时间量之后到期的令牌的类似的功能。如果你有流量的许多并能够证明一个CDN牺牲这种情况下,将很好地工作。 (注:与联CDN没有隶属关系,只挂因为我知道它们提供的功能)。

Push it off onto a CDN to handle. This is like option #3 (the one above), but uses a CDN to handle the file serving instead of your local server. Some CDNs such as EdgeCast provide a similar functionality where you set a token which expires after a set amount of time. This case will work nicely if you have a lot of traffic and can justify the expense of a CDN. (Note: no affiliation with the linked CDN, only linked because I know they offer the functionality).

至于如何我亲手做的,我已经做了所有以上。它真正重要的用例是什么。如果你正在构建的将是在共享的主机或您无法控制多个不同的服务器上安装一个系统,坚持第一个选项。如果你有完全的控制,并且需要节省服务器资源,做其他两个中的一个。

As far as how I'd personally do it, I've done all of the above. It really matters what your use-case is. If you're building a system that's going to be installed on shared hosts or multiple different servers which you don't control, stick to the first option. If you have full control and need to save server resources, do one of the other two.

注:的还有其他的选择比这三种。这些仅仅是最容易实现的,而大多数其他选项足以这些类似融入种类...

Note: there are other options than these three. These are just the easiest to implement, and most of the other options are similar enough to these to fit into the category...

这篇关于安全文件用PHP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-19 06:20