In modern web applications, securely sharing files while controlling access is crucial. Laravel provides an elegant solution for generating temporary URLs that expire after a specified time, ensuring your files remain protected. This article demonstrates how to implement temporary URLs in Laravel, covering route configuration, controller methods, and service provider adjustments.
Why Use Temporary URLs?
Temporary URLs allow you to grant time-limited access to files stored in your application. This prevents unauthorized sharing or prolonged access to sensitive resources. Laravel simplifies this process using signed URLs with expiration timestamps and cryptographic signatures.
Step 1: Create a Controller
Start by creating a FileController to handle URL generation and file streaming. The controller includes two methods:
getTemporaryUrl: Generates a signed temporary URL for the requested file.stream: Validates the URL signature and streams the file if valid.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
class FileController extends Controller
{
// Generate a temporary URL
public function getTemporaryUrl(Request $request)
{
$path = $request->query('path');
$expiration = now()->addMinutes(10); // URL expires in 10 minutes
$temporaryUrl = Storage::temporaryUrl(
$path,
$expiration
);
return response()->json(['url' => $temporaryUrl]);
}
// Stream the file after validating the URL
public function stream(Request $request)
{
// Validate the URL signature
if (!URL::hasValidSignature($request)) {
abort(403, 'Invalid or expired URL.');
}
$path = $request->query('path');
// Check if the file exists
if (!Storage::disk('local')->exists($path)) {
abort(404, 'File not found.');
}
// Stream the file
return Storage::disk('local')->response($path);
}
}
Step 2: Configure Routes
Define routes in routes/web.php to map requests to the controller methods. Assign names to the routes for easier reference in the service provider.
use App\Http\Controllers\FileController;
Route::get('file/stream', [FileController::class, 'stream'])->name('stream');
Route::get('file/generate', [FileController::class, 'getTemporaryUrl'])->name('generate');
Step 3: Customize Temporary URL Generation
Modify AppServiceProvider to override Laravel's default temporary URL logic. This links the URL generation to the named route stream and includes the file path as a parameter.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use DateTime;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
Storage::disk('local')->buildTemporaryUrlsUsing(
function (string $path, DateTime $expiration, array $options) {
return URL::temporarySignedRoute(
'stream',
$expiration,
array_merge($options, ['path' => $path])
);
}
);
}
}
How It Works
Generate a Temporary URL: A client requests a URL via
/file/generate?path=images/file.png. The server returns a signed URL like:http://127.0.0.1:8000/file/stream?expires=1736937021&path=images%2Ffile.png&signature=abc123The URL includes an expiration timestamp and a cryptographic signature.
- Access the File: When the URL is accessed, Laravel validates the signature and expiration time. If valid, the file is streamed directly from storage. Invalid or expired URLs return a
403 Forbiddenerror.
Benefits
- Security: Files are inaccessible without a valid signature.
- Controlled Access: URLs automatically expire, reducing the risk of unauthorized sharing.
- Efficiency: Files are streamed without exposing their storage path.
Conclusion
By leveraging Laravel's built-in features for signed URLs, you can enhance file security with minimal effort. This approach ensures sensitive resources remain protected while providing a seamless user experience. Adjust the expiration time and error handling to suit your application’s needs.
zakialawi
Comments