Запретить пользователям загружать другие файлы, изменив путь в запросе URL

#php #html #yii2

#php #путь #Скачать #обход пути

Вопрос:

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

метод:

 function actionDownload($arquivo) {
    try {
        $filepath = Yii::getAlias('@webroot') . '/files/coordenadas/'. $arquivo;
        if (file_exists($filepath)){
            return Yii::$app->getResponse()->sendFile(Yii::getAlias('@webroot') . '/files/coordenadas/'. $arquivo, $arquivo);
        }
    }
    catch (Exception $exception) {
        throw new NotFoundHttpException("Arquivo não encontrado");
    }
}

  

маршрут для загрузки метода:

http://example.com/converter-coordenadas/download?arquivo=geografica-utm-20200830171051.xlsx

если кто-то изменит arquivo переменную на другой допустимый путь, он сможет загружать другие файлы. Как предотвратить это, но сохранить функцию, получающую имя файла в параметре URL?

ситуация, с которой я столкнулся, такова:

  1. пользователь загружает файл через ajax
  2. я конвертирую этот файл и возвращаю имя файла
  3. создайте кнопку загрузки со ссылкой на новый файл.

У меня нет никакой другой информации для установления связи с файлом, например, идентификатора пользователя.

Комментарии:

1. Вероятно, ваш загружаемый файл вообще не отображается в URL. Вместо этого есть id , который ссылается на файл

2. Или вы можете зашифровать имя файла и сохранить его в отдельном поле базы данных вместе с оригинальным именем во время сохранения файла и показывать пользователю только зашифрованное имя. В своем действии вы проверяете, существует ли хэш в БД, и получаете необходимое исходное имя файла. Та же технология используется для восстановления пароля или проверки адреса электронной почты. Вы можете посмотреть там.

3. Я надеялся получить ленивый способ сделать это, используя что-то родное в php, чтобы разрешить доступ только к тому пути, который я хочу, но это более элегантный способ. спасибо @SergheiLeonenco

4. Добро пожаловать

Ответ №1:

Как объяснил @GetSet в комментариях, самая большая проблема — процедурная. Один из способов сделать это правильно заключается в следующем:

  1. Загрузите файл на свой сервер и сохраните ссылку в базе данных (вы уже делаете) и сгенерируйте уникальный идентификатор для этого файла (или для этой загрузки). Этот идентификатор будет сохранен в поле базы данных, например, с именем: «donwload_id».

  2. Затем в представлении (когда вы создаете ссылку для загрузки):

    Html::a('Download', [Url::to('donwload-action'), 'download_id' => $model- >download_id]);

  3. В вашем контроллере вы будете знать, как найти файл по его уникальному идентификатору (download_id).

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