Как я могу разрешить пользователю загружать файл, который хранится за пределами webroot?

Я разрабатываю систему, которая позволяет зарегистрированным пользователям (кто может быть кем угодно) загружать файлы. Я блокирую mime-типы и т. Д., Чтобы попытаться ограничить файлы типами .doc, .docx и .pdf, но для дополнительной безопасности они загружаются в папку вне webroot.

Другие пользователи могут затем загрузить файлы. Как я могу позволить им это сделать? Очевидно, я не могу просто связать файл с файлом, так как он находится вне webroot. Я не уверен, как добраться до файла! Я предполагаю, что могу использовать функции файла php для доступа к файлу, но как я могу «обслуживать его» для пользователя, который запросил его?

Какие последствия для безопасности могут иметь все это?

Благодарю.

Solutions Collecting From Web of "Как я могу разрешить пользователю загружать файл, который хранится за пределами webroot?"

Вам нужен скрипт PHP, который выполняет следующие действия:

  1. Правильно настройте заголовок содержимого (в зависимости от того, что пользователь загружает)
  2. Правильно настройте заголовок длины контента (в зависимости от размера файла)
  3. Откройте файл для чтения (вы можете использовать fopen)
  4. Прочитайте файл и выведите его содержимое в выходной поток
  5. Готово

Вы также можете использовать функцию 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; } ?> 

Вы можете поместить свой каталог файлов в корневой каталог и применить правила перезаписи мод для защиты и отображения виртуального пути к пользователям вместо реального пути.

Попробуйте следующее:

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

Для этого вам, вероятно, понадобится еще несколько заголовков, но вы должны понять, как это можно использовать.

См. Ответы на этот похожий вопрос. Обратитесь к файлу за пределами дерева веб-сайтов для загрузки , который ссылается на страницу руководства функции заголовка PHP .