Hope this helps you. Here is answer I posted in another thread:
https://laracasts.com/discuss/channels/laravel/private-file-access
I have a solution that uses public folder. When you upload files you can save them in whatever folder you want, you then save that folder in database together with filename. Then you generate a hash as well and use that in your route to access a particular file or you can use filename instead of hash, up to you. When you check the hash and find the coresponding file in the database you then serve that file from public folder directly from router.
Here is an example for images:
$image = Cache::rememberForever('image_'.$hash, function() use($hash){
return Image::where('hash', $hash)->first();
});
if($image == null)
abort(404, 'The image you are looking for could not be found.');
$imagefile = file_get_contents($image->path.'/'.$image->hash . '.' . $image->extension);
header('Content-type: image/jpeg;');
header("Content-Length: " . strlen($imagefile));
echo $imagefile;
user can't access any files in the public folder since they do not know where in what folder you save the files and since you render the file directly from controller function they will think if they type
www.yourwebsite.com/files/Yq4VgtC.jpg
that jpg image they just tried to access is actually stored directly under files folder when neither files folder exists nor that image directly under it.
Image could be somewhere like this
public/uploads/2016/12/28/15
so year/month/day/hour
etc that's just an example, you can store it where you want and noone will figure it out.
and before they can access any files you can use middleware to check if they are logged in if they try to access
www.website.com/files route
here is how a route can look for example image in my case:
Route::get('{hash}.{extension}', 'ImageController@image')->where('hash', '[a-zA-Z0-9-]+')->where('extension', '[jpg, jpeg, gif, png, mp4, bmp]+');
kieranst
3 weeks ago
(19,010 XP)
The issue with that is that the files are still exposed publicly as they are in the public area/folder. Yea it would be a lot harder to find (as your not giving away it's exact name or location), but still possible.
@kieranst
it's pretty much impossible to find the files using my system, I'd love you to prove me wrong :) You can block the folder listing in .htaccess so noone would be able to browse the folders by guessing folder names and you have no chance of finding a file if you do not know what kind of folder structure programmer used to store the files.
for example you could randomize the upload folder so that not even you know where it's uploaded
'public/uploads/2016/12/06/15/' . str_random(7) .'/filename.mp4';
No one no matter what software they used to scan your website would figure it out, and you could ofcourse block anyone using robots to probe your folder structure to find out files. No normal users would do this so it's pretty much safest way to do it if you indeed decide that you must use public folder to store files that should only be visible to certain users.