Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Senior Files

Як безпечно віддавати приватні файли користувачам?

Файл, покладений у storage/app, недоступний ззовні - це правильно за замовчуванням. Питання в тому, як віддати його тому, кому можна.

Що робити не варто: класти приватні файли в public/ чи публічний бакет і покладатися на те, що адресу ніхто не вгадає. Посилання розходяться, індексуються й лишаються робочими назавжди.

Спосіб 1 - віддати через контролер із перевіркою прав:

public function download(Document $document)
{
    $this->authorize('view', $document);

    return Storage::disk('private')->download($document->path, $document->name);
}

Кожне звернення проходить авторизацію. Мінус - файл іде крізь PHP, тож на великих файлах воркер зайнятий увесь час передачі.

Спосіб 2 - тимчасове підписане посилання до S3-сумісного сховища:

$url = Storage::disk('s3')->temporaryUrl($document->path, now()->addMinutes(5));

Посилання підписане й саме перестає працювати після строку. Файл віддає сховище напряму, PHP у передачі не бере участі - це те, що потрібно для великих файлів.

Спосіб 3 - підписаний маршрут, коли сховище тимчасових URL не вміє:

URL::temporarySignedRoute('documents.download', now()->addMinutes(5), ['document' => $document->id]);

Middleware signed перевіряє підпис і строк.

Про що часто забувають:

  • Спосіб 1 без authorize() перетворюється на публічний доступ через власний контролер.
  • Строк життя посилання має бути коротким: доки воно живе, ним може скористатися будь-хто, кому воно потрапило.
  • Імʼя файла від користувача не можна підставляти в шлях - Storage::putFile() генерує безпечне імʼя сам.

Докладніше в документації: Файлове сховище

2

Схожі питання