suther.land

Force file download from AWS S3 in Laravel

Amazon’s S3 is a great solution for storing files, and Laravel makes it easy to use. Occasionally you’ll need to force files to download instead of just showing it in the browser, but thankfully this is easy too! Rather than wasting your server resources to streaming the file from S3 to your user, we’re going to be using signed URLs.

Signed URLs can give a user temporary access to a specific file in your private bucket, so we just need to redirect there and tell S3 to set an extra header. In your controller responsible for downloading files, you’ll just need to return a response like below:

return redirect(Storage::disk('s3')->temporaryUrl(
    $file->path,
    now()->hour(),
    ['ResponseContentDisposition' => 'attachment']
));

In this example $file->path is the path of my file in my S3 bucket and now()->addHour() is creating a Carbon timestamp one hour in the future when our signed URL will expire. The important part is the ['ResponseContentDisposition' => 'attachment'] option which tells S3 our user wants to download the file rather than display it in the browser.