我很难为用户提供一个文件链接,让他们在登录时下载。我读了这个和那个(因为最终我想保护文件不受公众访问(。
因此,在我的应用程序/存储文件夹下,我在"public"旁边创建了一个"private"目录。里面有一个子文件夹"a",其中包含一个"fileA.tar.gz"(我也尝试过简单的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
时,我得到404,尽管exists
函数返回true
。
因此,我尝试在/config/filessystems.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(。
请注意:如果我保留相同的子目录层次结构,并将其移动到public下,如:
MyLaravelApp/
├── storage/
│ ├── public/
│ └── A/
│ └──fileA.tar.gz
│ ├── private/
没有问题,文件可以下载。这并不有趣,因为我想防止这个文件在没有登录的情况下被下载
根据文档和其他SO的回答,似乎可以访问与public
不同的目录。如何做到这一点?为什么exists()
返回true而我得到404?我的设置/代码故障到底是什么?
感谢您的帮助!
解决方案
根据@Namoshek的回答,以下是我所做的(记录(:
在前面提到的控制器中,我简单地检查了用户是否有权下载文件A。如果是这样,那么我返回一个视图,该视图具有到名为downloadFileA
的路由的链接,该路由指向仍在相同的前述控制器中的函数downloadFileA
。
最后,在函数downloadFileA
中,我在检查用户是否有权下载文件后返回Storage::disk('private')->download('fileA')
。所以我检查了两次,但这不是问题,因为交通量很低(大约一周一次(。
您可以使用Storage::download('filename.xyz')
而不是使用Storage::url('filename.xyu')
生成URL。这将把文件作为响应的内容发送。不过,对于大文件来说,这可能是资源密集型的。