PHP make文件仅在代码中可用

时间:2013-02-05 10:30:51

标签: php html security

您是否知道是否可以通过单击代码中的链接使文件仅可供下载,并通过复制/粘贴地址栏中的URL来尝试访问该文件来限制访问?

示例:

我以PDF格式生成发票,我想让它们仅供登录客户使用,并且只能为此特定客户生成的发票。客户A不允许查看客户B的发票,反之亦然。

现在我在这里保存这些发票: www.mydomain.com/invoices /

并且客户A的发票如下: www.mydomain.com/invoice/20130202_120045.pdf

现在,我希望当我在HTML中添加这样的链接时,客户才能看到此PDF:

<a href="http://www.mydomain.com/invoice/20130202_120045.pdf">See invoice</a>

但不能通过在地址栏中直接输入www.mydomain.com/invoice/20130202_120045.pdf来访问PDF。

这在某种程度上是可能的吗?

3 个答案:

答案 0 :(得分:4)

有多种方法,但我认为这是最简单的方法:

  • 将实际PDF存储在只能由PHP访问的目录中(例如,在您的Web根目录之外或由.htaccess阻止)。
  • 验证PHP脚本中的访问权限。
  • 让我们使用标题Content-disposition通过PHP脚本进行下载,以设置文件名并使用readfile()输出文件内容。

答案 1 :(得分:2)

当然 - 最简单的方法是使用 .htaccess 。您可以将所有不能通过URL下载的文件存储在一个文件夹中,然后将所有文件重定向到PHP脚本。

这样,当一个人试图下载http://www.mydomain.com/invoice/20130202_120045.pdf时,他们将(在后台,通过.htaccess)重定向到某个地方的PHP脚本。

如果此人已获得授权(通过会话,cookie ...),那么PHP脚本可以 验证 ,并且只有输出原始文件(或错误消息)如果他们不是)。

您可以使用 fgets() 功能分批输出文件,以确保不会使服务器上的内存过载。

这种方法的缺点可能是可伸缩性,因为用户下载的文件越多,需要运行的PHP脚本就越多,并且可能会在某些时候使Apache过载。但如果代码写得好(即使用 fgets() 等),那就不太可能了。)

答案 2 :(得分:0)

使用mod_xsendfile这很容易。您将文件粘贴在文档根目录之外,并发出一个特殊的标题,告诉Apache代表您发送文件:

设置完成后,代码就像这样简单:

<?php
...
if ($user->isLoggedIn())
{
    header("X-Sendfile: $path_to_somefile");
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"$somefile\"");
    exit;
}
?>
<h1>Permission denied</h1>
<p>Login first!</p>

源代码取自模块页面本身。