如何允许用户下载存储在webroot外部的文件?

时间:2010-12-03 12:03:07

标签: php security file-upload download

我正在开发一个允许注册用户(可能是任何人)上传文件的系统。我阻止了mime-types等,试图将文件限制为.doc,.docx和.pdf类型,但为了提高安全性,它们被上传到webroot之外的文件夹。

然后,其他用户可以选择下载文件。我如何允许他们这样做?显然,我不能只是放入文件的链接,因为它在webroot之外。我不知道如何到达该文件!我认为我可以使用php文件函数来访问该文件,但是如何向请求它的用户“提供”呢?

这可能会带来什么安全隐患?

感谢。

4 个答案:

答案 0 :(得分:10)

您需要一个执行以下操作的PHP脚本:

  1. 正确设置内容类型标题(取决于用户正在下载的内容)
  2. 正确设置内容长度标题(取决于文件大小)
  3. 打开文件进行阅读(可以使用fopen)
  4. 读取文件并将其内容输出到输出流
  5. 完成
  6. 您也可以使用readfile功能基本相同。以下是PHP网站的一个例子:

    <?php
    $file = 'monkey.gif';
    
    if (file_exists($file)) {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($file));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));
        ob_clean();
        flush();
        readfile($file);
        exit;
    }
    ?>
    

答案 1 :(得分:0)

答案 2 :(得分:0)

您可以将您的文件目录放在root中并应用mod重写规则来保护并显示用户的虚拟路径而不是真实路径。

答案 3 :(得分:0)

尝试以下方法:

$fileName = basename($_GET['file']);
$path = 'path/to/data/'.$fileName;

// define $mimeType and $isAuthenticated

if ($isAuthenticated && file_exists($path)) {
    // serve file
    header('Content-type: '.$mimeType);
    header('Content-Disposition: attachment; filename="'.$fileName.'"');
    readfile($path);
} else {
    // 404
}

这可能需要更多的标题以满足您的需求,但您应该知道如何使用它。