Laravel 5.7:404或403在存储/app/private上,而它在存储/ap/public上工作



我很难为用户提供一个文件链接,让他们在登录时下载。我读了这个和那个(因为最终我想保护文件不受公众访问(。

因此,在我的应用程序/存储文件夹下,我在"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。这将把文件作为响应的内容发送。不过,对于大文件来说,这可能是资源密集型的。

最新更新