我正在努力为用户提供指向他们登录时可以下载的文件的链接。我读了this和that (because eventually I want to protect the file from public access)。
因此,在我的应用程序/ storage文件夹下,我在“公共”旁边创建了一个“私有”目录。在其中有一个包含“ fileA.tar.gz”的子文件夹“ A”(我也尝试过使用没有运气的简单test.txt文件)。
MyLaravelApp/
├── storage/
│ ├── public/
│ ├── private/
│ └── A/
│ └──fileA.tar.gz
在我的控制器中,我做
$softwarePath = "private/A/fileA.tar.gz";
$urlToArchive = \Storage::disk('local')->url(
$softwarePath);
$exists = \Storage::disk('local')->exists($softwarePath); // returns true
但是在视图中,当我单击链接http://127.0.0.1:8000/storage/private/A/fileA.tar.gz
时,尽管exists
函数返回了true
,但我得到了404。
因此,我尝试在/config/filesystems.php中为我的“私人”文件夹定义直接的“快捷方式”:
'private' => [
'driver' => 'local',
'root' => storage_path('app/private'),
'url' => env('APP_URL').'/privateDownload',
'visibility' => 'public',
],
并在控制器中进行了以下更改:
$softwarePath = "A/fileA.tar.gz";
$urlToArchive = \Storage::disk('private')->url($softwarePath);
$exists = \Storage::disk('private')->exists($softwarePath); // keeps returning true
但是现在,当我单击生成的链接http://localhost/privateDownload/A/fileA.tar.gz
(注意没有端口地址的localhost)时,我得到403,如果将地址更改为localhost:8000,我会得到404。
到上述控制器的路由为:
Route::get('/account', 'AccountController@showAccountDetails')->middleware('auth');
我还尝试删除middleware('auth')
并访问private/A/fileA.tar.gz
,但没有运气(404)。
请注意:如果我保留相同的子目录,并将其移至公共位置,如:
MyLaravelApp/
├── storage/
│ ├── public/
│ └── A/
│ └──fileA.tar.gz
│ ├── private/
没有问题,可以下载文件。这并不有趣,因为我想防止未登录就下载该文件。
根据doc和其他SO答案,似乎可以访问不同于public
的目录。怎么做到呢 ?为什么exists()
返回true,而我却得到404?究竟我的设置/代码失败是什么?
任何帮助表示赞赏!
解决方案
根据@Namoshek的回答,这是我所做的(用于记录):
在上述控制器中,我只是简单地检查了用户是否有权下载文件A。如果是这样,那么我返回一个视图,该视图具有指向名为downloadFileA
的路由的链接,该路由指向仍在上述控制器中的函数downloadFileA
。
最后,在功能downloadFileA
中,在检查用户是否有权下载文件后,我返回\Storage::disk('private')->download('fileA')
。因此,我检查了两次,但这不是问题,因为流量非常低(一周左右)。
答案 0 :(得分:1)
您可以使用Storage::download('filename.xyz')
代替使用Storage::url('filename.xyu')
生成URL。这将发送文件作为响应的内容。不过,对于大文件而言,这可能会占用大量资源。