2011-02-14 38 views
1

我有一个简单的登录/访问控制系统来保护一些受限制的页面,但在这些页面中有需要安全的链接,即Word文档。因此,如果我将这些资源保存在webroot中,则可以通过URL访问这些资源。保护限制页面内的这些资源的最佳方法是什么?我知道我可以用密码保护文件夹,但用户会被挑战两次,一次是限制页面,然后是资源链接。有什么建议?用PHP保护文档

回答

12

这里有几个选项,具体取决于您的使用情况。

  1. 使用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服务该文件时,它不能服务另一页),因为这样的好处...

  2. 使用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。

  3. 使用诸如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秒)...

  4. 将它推到CDN上进行处理。这就像选项#3(上面的那个),但使用CDN来处理文件服务而不是本地服务器。一些CDN如EdgeCast提供了一个类似的功能,您可以设置在设定时间后过期的令牌。如果你有一个lot的流量,并且可以证明CDN的费用合理,这种情况将很好地发挥作用。 (注意:与链接的CDN没有关联,因为我知道它们提供了功能,所以只关联)。

至于我个人如何做,我已经完成了以上所有。它真的很重要你的用例。如果您正在构建要安装在共享主机或多个不受控制的不同服务器上的系统,请坚持第一个选项。如果您完全控制并需要节省服务器资源,请执行其他两项任务之一。

注意:还有其他的选择,除了这三个。这些只是最容易实现的,并且大多数其他选项足够类似于这些以适合类别...

+0

我只使用第一种方法,但其他两种看起来很有趣。如果将其与X-SendFile进行比较,mod_auth_token的性能如何? 此外,这让我想我可以优化一个缩略图类,如果它已经被调整大小,我得到了一个缓存文件流,我想我可能可以通过使用X-SendFile来获得一些性能。 – Hultner 2011-02-14 14:34:14

0

我还没有用Word文档(只有图片)试过它,但我会尝试直接从php,see my answer about images提供文档。

它会像链接到一个php页面的a标签,该页面将Word文档作为其内容类型。

+0

只要给出正确的标题,就应该工作。不要忘记阻止访问您上传实际文档的文件夹。如果你使用apache,你可以使用``.htaccess文件中的全部拒绝来做到这一点。通过头文件你也可以强制用户下载文件。 – Hultner 2011-02-14 14:27:45