Upload files outside of webroot

2020-08-05 11:03发布

问题:

I'm developing a shopping system where shopmanager should be able to upload files to the system. Those files can the be sold for a fee and should only be accesible through providing a purchase code.

The whole purchase code and uploading thing is working fine. Just have to block the direct access to the file.

Questions:

  • How can I allow users to upload outside of webroot but not read/download from there?
  • Or How do I allow users to upload to a directory but no one can read/download from it?

I'm running Apache and use code like this to upload files via a form:

 public function upload_file($file='',$post_value='',$path) {
  if ($_FILES[$post_value]) {
      $uploadext = strtolower(strrchr($_FILES[$post_value]['name'],"."));
      if($uploadext=='.jpg' || $uploadext=='.gif' || $uploadext=='.png' || $uploadext=='.swf' || $uploadext=='.jpeg' || $uploadext=='.pdf' || $uploadext=='.doc' || $uploadext=='.xls' || $uploadext=='.docx') {
    $destination = $path.$file.$uploadext;
       move_uploaded_file($_FILES[$post_value]['tmp_name'], $destination);
   } else {
    echo PICTURE_ERROR;
   }
  }
  return $file.$uploadext;
 }

回答1:

you can upload where ever you want using the move_uploaded_file function, just make sure the webserver can write in the destination directory.

After you have to create a script that would read the file and pass it to the browser so you can make sure user have paid the file.

exemple

<?php
// insert your logic here to verify the user has access to this file.
// open the file in a binary mode
$name = 'yourfile';

$fp = fopen($name, 'rb');

// send the right headers
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));

// dump the picture and stop the script
fpassthru($fp);
exit;

?>

You have to be careful about the content-type also make sure the user cannot every file of your server if you use a $_GET variable for getting the filename.



回答2:

That's actually pretty easy. Just create a directory for your files and give apache permissions to write to it. Then when you call move_uploaded_file() function you can just specify the destination to that directory. PHP operates server side so it will be able to access that directory, while users using the browser will be limited to only what Apache will allow them to access.

If you ever need to download these files, just create a script that will parse URL parameter (or something) and take the file from the files directory and push it to the browser.



回答3:

use a .htaccess file or configure in apache.conf to not allow direct access to the upload dir.

<Directory /path/to/upload/dir>
   Order Deny,Allow
   Deny from All
</Directory>


回答4:

It would probably be easiest, in terms of securing the file, to save the files outside your webroot. When somebody wants to download it, you can use http_send_file to send the file back out to them.