Как бы хранить файлы вне общего доступа но давать ссылку авторизованным?

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

Существует несколько способов реализации данной функциональности в Laravel, но наиболее эффективным методом является использование промежуточного обработчика (middleware) и хранение файлов в защищенной директории на сервере.

Следуя принципу "скрыть, но не защищать", промежуточный обработчик будет отвечать за проверку авторизации пользователя и предоставление доступа к файлам. Для этого выполним следующие шаги:

Шаг 1: Создание защищенной директории для хранения файлов
Создайте директорию на сервере, к которой не будет доступа напрямую через браузер. Например, вы можете создать директорию с названием "uploads" в корневой папке проекта и добавить ее в файл .gitignore, чтобы она не попала в систему контроля версий.

Шаг 2: Определение промежуточного обработчика
Создайте новый класс middleware с помощью команды artisan:

php artisan make:middleware AuthFileAccess

Откройте файл app/Http/Middleware/AuthFileAccess.php и замените его содержимое следующим кодом:

<?php

namespace AppHttpMiddleware;

use Closure;
use IlluminateSupportFacadesAuth;

class AuthFileAccess
{
    public function handle($request, Closure $next)
    {
        if (!Auth::check()) {
            abort(403, 'Unauthorized');
        }

        return $next($request);
    }
}

Данный промежуточный обработчик будет проверять, авторизован ли пользователь, и в случае отсутствия авторизации будет возвращать ошибку 403.

Шаг 3: Регистрация промежуточного обработчика
Откройте файл app/Http/Kernel.php и добавьте в массив $middleware следующую строку:

protected $middleware = [
    // ...
    AppHttpMiddlewareAuthFileAccess::class,
];

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

Шаг 4: Работа с файлами
В контроллере или маршруте вашего приложения добавьте код для предоставления доступа к файлам:

public function downloadFile($filename)
{
    $filePath = storage_path('app/uploads/' . $filename);

    if (!file_exists($filePath)) {
        abort(404, 'File not found');
    }

    return response()->download($filePath);
}

Данный метод будет принимать имя файла как параметр и формировать путь к соответствующему файлу в директории "uploads". Затем происходит проверка наличия файла и, при его наличии, создается заголовок ответа для скачивания файла пользователем. Если файла нет, будет возвращена ошибка 404.

Шаг 5: Создание маршрута
Добавьте маршрут в файл routes/web.php для обработки загрузки файла:

Route::get('/download/{filename}', 'SomeController@downloadFile')
    ->middleware('auth.file.access');

Строка ->middleware('auth.file.access') указывает на применение промежуточного обработчика AuthFileAccess к данному маршруту.

Шаг 6: Завершение
Теперь вы можете генерировать ссылку на загрузку файла для авторизованных пользователей, используя маршрут, который вы создали в шаге 5:

$url = route('download', ['filename' => 'file.pdf']);

Замените "file.pdf" на имя вашего файла.

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

Важно отметить, что этот подход не обеспечивает полную защиту файлов. Пользователи, получившие доступ к файлу, смогут поделиться ссылкой с другими пользователями. Если вам требуется более сложная система управления доступом, вам следует рассмотреть использование более продвинутых инструментов, таких как AWS S3 или Google Cloud Storage, в комбинации с механизмами аутентификации Ларавел.