【问题标题】:PHP make file only available in codePHP 使文件仅在代码中可用
【发布时间】:2013-01-20 06:00:32
【问题描述】:

您知道是否可以通过单击代码中的链接使文件仅可供下载,并通过尝试通过复制/粘贴地址栏中的 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。

这在某种程度上可能吗?

【问题讨论】:

标签: php html security


【解决方案1】:

有多种方法,但我想说这是最简单的一种:

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

【讨论】:

  • +1 for readfile(),从未使用过,甚至不知道它存在 :)
【解决方案2】:

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

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

该 PHP 脚本然后可以验证此人是否已获得授权(通过会话、cookie...),并且仅在授权时才输出原始文件(或错误消息如果不是)。

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

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

【讨论】:

    【解决方案3】:

    使用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>
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-31
      • 2011-11-18
      • 1970-01-01
      • 2011-07-15
      • 2012-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多