Загрузка файла: каково должно быть имя файла для сохранения?

Я собираюсь добавить элемент управления загрузкой файлов на свою веб-страницу ASP.NET 2.0, чтобы пользователи могли загружать файлы. Файлы будут храниться на сервере в папке с именем пользователя. Я хочу знать, что лучше всего назвать файлы при сохранении на сервере. Необходимо учитывать безопасность, производительность, гибкость при работе с файлами и т.д. Если я пропущу что-нибудь, пожалуйста, направляйте меня

Параметры, которые я рассматриваю сейчас:

  • Загрузка с тем же именем, что и имя входного файла
  • Добавить идентификатор пользователя + случайное число + имя файла с именем входного файла
  • Создайте случайные числа + Текущее время в секундах и сохраните файлы с этим номером. Будет иметь одну таблицу для сопоставления этого номера с загрузкой пользователей.

Что-нибудь еще? Каков наилучший способ?

Заранее спасибо

Ответ 1

НИКОГДА НЕ используйте пользовательский ввод для имен файлов. Не используйте имя пользователя. Вместо этого пользователь вводит идентификатор пользователя (я предполагаю, что ваши пользователи имеют уникальный идентификатор).

НИКОГДА не используйте исходное имя файла. Используйте номер решения 3, плюс идентификатор пользователя вместо имени пользователя.

Для вашей информации PHP имел уязвимость несколько лет назад: можно было создать запрос HTTP POST с загрузкой файла и с именем файла, например "../../anything.php", и php _FILES массив, который должен содержать дезинфицированные значения, не обнаруживал такие имена файлов, поэтому можно было записывать файлы в любом месте файловой системы.

Ответ 2

Я бы использовал комбинацию

  • Идентификатор пользователя
  • Случайная сгенерированная строка (например, GUID)

Пример имени файла PDF: 23212-dd503cf8-a548-4584-a0a3-39dc8be618df.pdf

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

Я не вижу необходимости включать какую-либо другую информацию в имя файла, поскольку время/дата загрузки и т.д. могут быть получены из атрибутов файла.

Кроме того, вы должны хранить файлы в безопасном месте, к которым не могут обращаться внешние пользователи, такие как посетители вашего сайта. Вместо этого вы доставляете файл им через прокси-страницу (вы читаете файл из безопасного места и передаете данные пользователю). Для этого решения необходима база данных для отслеживания файлов, их местоположения и т.д.

Это также позволяет вам контролировать, какие пользователи имеют доступ к каким файлам через ваш код.


Обновление: Здесь описано, как может быть реализовано решение с веб-страницей прокси.

  • Создайте веб-форму с именем GetFile.aspx
  • GetFile.aspx принимает один параметр запроса с именем fileid, который используется для идентификации файла для получения. Например:
     http://www.mypage.com/GetFile.aspx?fileid=100
  • Используйте параметр fileid для поиска местоположения файла в базе данных, чтобы его можно было прочитать и отправить пользователю. В веб-форме вы используете Request.QueryString("fileid"), чтобы получить идентификатор файла и использовать его в запросе, который будет выглядеть примерно так (SQL):
    SELECT FileLocation FROM UserFiles WHERE FileID = 100
  • Прочитайте файл с помощью System.IO.FileStream и выведите его содержимое через Response.Write. Не забудьте установить соответствующий тип контента, используя Response.ContentType, чтобы браузер клиента правильно обрабатывал запрошенный файл (см. этот пост в asp.forums.net и статья MDSN, которая также упоминается в сообщении, в котором оба автоматически обсуждают метод определения соответствующего типа контента.)

Если вы выберете этот подход, вы легко сможете реализовать свои собственные простые действия безопасности или пользовательские действия позже, например, убедиться, что пользователь зашел на ваш веб-сайт перед отправкой файла или что пользователи могут получать доступ только к файлам, которые они загружали самостоятельно или регистрировать, какие пользователи скачивают файлы и т.д. Возможности бесконечны; -)

Ответ 3

Взгляните на класс System.IO.Path, поскольку у него есть много полезных функций, которые вы можете использовать, например:

Проверьте, какие символы недопустимы в имени файла:

System.IO.Path.GetInvalidPathChars();

Получить произвольное имя файла:

System.IO.Path.GetRandomFileName();

Получите уникальное имя файла randome во временном каталоге

System.IO.Path.GetTempFileName();

Ответ 4

Я бы пошел с опцией №3. Таблица, отображающая эти файлы с пользователями, будет использовать другие способы использования в будущем, это всегда так. Если вы используете сопоставление, единственное преимущество добавления имени пользователя или идентификатора в файл - это если вы пытаетесь отладить проблему.

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

  • Нет имени пользователя как части имени файла как любой части сохраненного файла
  • Никогда не используйте исходное имя файла как любую часть сохраненного файла
  • Используйте случайное число или идентификатор GUID для обеспечения отсутствия дубликата файла
  • Добавление идентификатора пользователя в файл поможет с проблемами ручной отладки

Ответ 5

Это больше, чем кажется на первый взгляд..., о котором я думаю, что вы уже знали!

О каких файлах вы говорите? Если они что-то даже отдаленно большие или в таком количестве, что группа файлов может быть большой, я сразу же предлагаю вам добавить некоторую гибкость в ваш подход.

  • создайте таблицу, в которой хранятся корневые пути к различным хранилищам файлов (это могут быть диски, пути, пути, поддерживаемые вашей средой). Сначала у него будет одна запись, которая станет вашим первым местом хранения. Хорошим атрибутом для поддержания этих данных является то, сколько места можно сохранить здесь.
  • сохранить таблицу данных, связанных с файлом (id {guid}, создать дату, внешний ключ для данных пути, размер файла)
  • напишите файл корневому файлу, на котором все еще есть место (запросите все размеры файлов, хранящиеся в корневом каталоге, и сравните их с емкостью корней)
  • напишите файл с помощью GUID для имени (обфускации файла в файловой системе).. могут быть записаны без расширения файла, если для этого требуется безопасность (конфиденциальные файлы)
  • напишите файл в соответствии с его датой создания, начиная с корня/года {числа}/месяца {числа}/день {номер}/файла.экземпляра

С такой системой на месте - даже если вам это не понадобится/не нужно - вы теперь можете легко перемещать файлы. Вы можете лучше управлять файлами. Вы можете лучше управлять коллекциями файлов. И т.д. Я использовал эту систему раньше и нашел ее довольно гибкой. Работа с файлами, которые хранятся в файловой системе, но управляемые из базы данных, могут немного выходить из-под контроля, когда хранилище файлов становится таким большим, и что-то нужно немного перемещать. Кроме того, по крайней мере, в случае с окнами... хранение zillions файлов в одном каталоге обычно не является хорошей идеей (причина для разбивки на их дату создания).

Эта сложность действительно нужна только тогда, когда у вас большие объемы и большие отпечатки ног.