На нашем сайте мы используем cookie для сбора информации технического характера и обрабатываем IP-адрес вашего местоположения. Продолжая использовать этот сайт, вы даете согласие на использование файлов cookies. Здесь вы можете узнать, как мы пользуемся файлами cookies.
Я согласен
логотип upread.ru

Отдача файлов в Laravel с ограниченным доступом



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



Предварительные мысли и ход решения

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

  • Создаем роут для скачивания документов
  • Создаем контроллер для скачивания документов
  • В контроллере создаем две функции
    1. Для принудительного скачивания файлов (чтобы браузер не показывал картинку) и потом удаления его
    2. Получающую на вход запрос как аргумент, проверяющую пользователя, копирующую файл из хранилища (storage) в общедоступную папку и вызывающую первую функцию.
Таким образом, пользователь будет отправлять запрос, ларавель при этом проверит его права, затем скопирует файл, даст скачать и удалит из общедоступной папки.

Непосредственно код

В файл роутинга routes/web.php добавляем правило

Route::get('/docs/{idx}', [DocumentController::class, 'getFile'])->middleware(['auth'])->name('docs');
Первая функция для скачивания файлов браузером посетителя

    function file_force_download($file) {
        if (ob_get_contents()) ob_end_clean();
        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');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));
        readfile($file);
        unlink($file);
        exit;
    }
Вторая функция (обе находятся в классе DocumentController)

    public function getFile(Request $request, String $idx = "" )
    {
        if (!$idx){
            return;//тут можно в принципе и сообщение об ошибке и abort(404)
        }

                $docname = DB::table('documents')
                ->where('id', $idx)
                ->where('user_id', Auth::user()->id)
                ->first();
        if (!$docname){
            return;//тут можно в принципе и сообщение об ошибке и abort(404)
        }


      //копируем файл
        $path = storage_path('app/docs/'. $idx);
        $newfile = "/home/каталог_сайта/public_html/tmp/". $idx;
        copy($path, $newfile);

        //отдаем его посетителю
        $this->file_force_download($newfile);
Здесь мы сначала проверяем, есть ли вообще аргумент, потом предполагаем, что данный аргумент – это индекс документа в таблице documents и что владелец данного файла именно текущий, авторизованный пользователь – что именно он пытается осуществить скачивание. Теперь если зарегистрированный пользователь хочет скачать свой файл, то он переходит по адресу https://сайт/docs/ид_файла, ларавель копирует файл в папку https://сайт/tmp/ид_файла и дает скачать. Потом удаляет.

Итоги

Вот так несложно можно скачивать файлы с Laravel. Напоследок обращу внимание на один момент, на который стоит обратить внимание, если у вас на сервере-сайте будет храниться уж очень конфиденциальная информация. Можно дополнительно сделать так, чтобы файл копировался во временную папку со случайным названием из набора букв и цифр. Хотя и так он просуществует в доступном месте буквально пару секунд.



Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, laravel, php





Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.



Программа для тестов: подключаем Firebird
Урок 10. Операторы побитового сдвига C#


© upread.ru 2013-2023
При перепечатке активная ссылка на сайт обязательна.
Задать вопрос
письмо
Здравствуйте! Вы можете задать мне любой вопрос. Если не получается отправить сообщение через эту форму, то пишите на почу up777up@yandex.ru
Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.