@tray2 @newbie360 @michaloravec @jlrdw I found a solution to protect images and serve the images only to users who actually have access to the page and block users from directly going to the image URL in the browser! (Using nginx, not sure how it's with other servers)
I copy this answer from my other post (Because those were 2 similar posts that lead to the same issue):
I am using nginx X-Accel-Redirect header.
What I did was to add a location block in my nginx config with internal directive:
location /uploads{
internal;
}
Now when I go directly to mysite.test/uploads/image.jpeg (In the browser) I get 404 response from nginx
So in order to view the image, what I do is, I set the path to a Laravel controller in the <img> element containing some identifier to get the image path from the DB, for example:
<img src="mysite.test/image_id?id=1">
Then web.php redirects to the controller:
Route::get('image_id', [Controller::class, 'get_image']);
Then the Controller returns an empty response with X-Accel-Redirect header:
public function get_image(Request $request)
{
$image = Image::find($request->id);
$image_path = $image->path;
return response('')->header('X-Accel-Redirect', $image_path);
}
And then this header tells nginx that I can access this image and it shows up!
I can even set alias for the uploads folder so it won't be the same as the actual path to further obscure it. It's quite cool.
So the entire flow now is:
- User go to
/mysite.test/images/
- The Laravel Backend returns list of images to show and the frontend appends them as list of
<img>s
- Each
<img> element in turn sends a GET request to Laravel backend again and gets a response with X-Accel-Redirect and show the image!