简体   繁体   中英

How can I allow a user to download a file which is stored outside of the webroot?

I am developing a system which allows registered users (who could be anybody) to upload files. I've block mime-types etc. to attempt to restrict the files to .doc, .docx and .pdf types, but for additional security, they are uploaded to a folder outside the webroot.

Other users can then choose to download the files. How do I allow them to do that? Obviously I can't just put in a link to the file, as it's outside the webroot. I'm not sure how to reach the file though! I presume I can use the php file functions to get to the file, but how do I then 'serve it up' to the user who has requested it?

What security implications might all of this have?

Thanks.

You need a PHP script that does the following:

  1. Set the content-type header correctly (depending on what the user is downloading)
  2. Set the content-length header correctly (depending on the file size)
  3. Open the file for reading (you can use fopen)
  4. Read the file and output its content to the output stream
  5. Done

You can also use readfile function to do basically the same. Here's an example from PHP's site:

<?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;
}
?>

请参阅此类似问题的答案: 请参阅网站树外的文件以进行下载 ,该文件链接到PHP标题功能手册页

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

Try the following:

$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
}

This will probably need some more headers to suit your needs, but you should get an idea how this can be used.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM