You cannot access any files outside of the /public folder from the browser and any file in there is available on the web if the visitor knows the name of the file. The hash name already helps preventing that, but if you need total security you can create a small Controller to handle the download of the file when the user types, for example, http://your-site.com/docs/the-doc-here.pdf. You then use the Response class to download the file from storage and show it in the browser. As long as you have a middleware in that controller you will be safe from unauthorized visitors.
class FileController extends Controller {
public function __construct()
{
// This will block anyone who is not registered from continuing with this request
$this->middleware('auth');
}
public function getFile($filename)
{
// The Response class has the helper function response() that you can use
return response()->download(storage_path($filename), null, [], null);
}
}
The last argument in download() being null prevents the Content-Disposition header being set to attachment. In other words, the browser won't ask you save the file, but just show it.
Then in the route you can have
Route::get('/docs/{filename}', 'FileController@getFile');
If you want to be specific about the characters used naming the file you can add this to the route
Route::get('/docs/{filename}', 'FileController@getFile')->where('filename', '^[^/]+$');;
Now the file is located only on the storage folder. When an authenticated user makes the request on the browser, it will be displayed but not downloaded or permanently saved on the public folder.