php 41 lines · 6 steps

Time-limited signed download links in Laravel

A controller that hands out expiring, tamper-proof URLs and streams the file only when the signature checks out.

Explained by highlit
1<?php
2 
3namespace App\Http\Controllers;
4 
5use App\Models\Document;
6use Illuminate\Http\Request;
7use Illuminate\Support\Facades\Storage;
8use Illuminate\Support\Facades\URL;
9use Symfony\Component\HttpFoundation\StreamedResponse;
10 
11class DocumentDownloadController extends Controller
12{
13 public function generate(Request $request, Document $document)
14 {
15 $this->authorize('download', $document);
16 
17 $url = URL::temporarySignedRoute(
18 'documents.download',
19 now()->addMinutes(15),
20 ['document' => $document->id]
21 );
22 
23 return response()->json([
24 'download_url' => $url,
25 'expires_at' => now()->addMinutes(15)->toIso8601String(),
26 ]);
27 }
28 
29 public function download(Request $request, Document $document): StreamedResponse
30 {
31 abort_unless($request->hasValidSignature(), 403, 'This download link has expired.');
32 
33 $disk = Storage::disk($document->disk);
34 
35 abort_unless($disk->exists($document->path), 404);
36 
37 return $disk->download($document->path, $document->original_name, [
38 'Content-Type' => $document->mime_type,
39 ]);
40 }
41}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Signed URLs let you delegate access without exposing storage paths or requiring a session on the download itself.
  2. 2Splitting link generation from the actual download keeps authorization and delivery as separate, verifiable steps.
  3. 3Streaming through the Storage facade avoids loading the whole file into memory and works across local and cloud disks.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Time-limited signed download links in Laravel — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code