Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

mathewp's avatar

How can we protect uploaded images and pdf files in laravel

Hi all, i want to upload some copy protected images in my site. How can I protect it from public download. Is it secure in public folder

0 likes
7 replies
laracoft's avatar

@mathewp

  1. Please define what "copy protected" means
  2. Public folder can be downloaded by anyone who has the link, so answer is no.
Niush's avatar

My suggested approach.

For Publicly viewable Files Store it with 'public' filesystem disk.

if(request()->hasFile('image') && request()->file('image')->isValid()){
     $post->image = request('image')->store('post', 'public');
}

So if you visit myurl/storage/post/filename.jpeg it is visible. To get url Storage::url(Post::first()->image)

For Private files store without 'public' filesystem disk or 'local' by default.

if(request()->hasFile('image') && request()->file('image')->isValid()){
     $post->image = request('image')->store(auth()->user()->id.'/post');
}

The path is myurl/user_id/post/filename.jpeg. But this path is not served from public so is hidden.

Then, finally to access the file create a route in web.php that takes the image url as param.

// Where url can be generated with Storage::url(Post::first()->image)
Route::get('storage/{url}', function ($url) {
    $user_id = request()->segments()[1] ?? null; // get user_id from url
    if (!$user_id || !Storage::exists($url) || $user_id != auth()->user()->id){
       abort('404');
    }
    $path = storage_path('app' . DIRECTORY_SEPARATOR . $url);
    return response()->file($path);
})->where(['url' => '.*']);

Note: If you use AWS S3 then look into File Visibility. https://laravel.com/docs/8.x/filesystem#file-visibility

Snapey's avatar

Your options are;

  1. hold the file in a public place but with a long, impossible to guess, filename

  2. hold the file in a private place and only stream it to the user when they have proved their credentials. This option requires that PHP streams the file, and not your webserver so there can be some performance hit.

option 1 is simple, but anyone with the filename can access the file. No good for resources that should be restricted, eg subscribers to a course where you don't want the links shared to non-subscribers, but good for things like pdf invoices where the user can share their invoice with someone else if they want, but you need to stop someone looking at every invoice in the system

What is the use case?

mathewp's avatar

I want to store the images in app/public folder and display the same in blade file without a symbolic link to public folder. Because i am using a shared host and not able to create a link

jlrdw's avatar

Write a script to serve image. But secure images doesn't need to be anywhere in laravel , but somewhere else on filesystem.

If you have customers secure images, it sounds like you need better hosting.

Please or to participate in this conversation.