【问题标题】:Laravel 5.7 : 404 or 403 on storage/app/private whereas it works on storage/app/publicLaravel 5.7 : storage/app/private 上的 404 或 403 而它在 storage/app/public 上工作
【发布时间】:2019-04-24 16:04:31
【问题描述】:

我正在努力为用户提供一个他们可以在登录后下载的文件的链接。我阅读了thisthat (because eventually I want to protect the file from public access)

因此,在我的应用程序 /storage 文件夹下,我在“public”旁边创建了一个“private”目录。在它里面有一个包含“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 时得到 403(注意没有端口地址的 localhost),如果我将地址更改为 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/

没有问题,可以下载文件。这并不有趣,因为我想防止在未登录的情况下下载此文件。

根据doc 和其他 SO 答案,似乎可以访问与public 不同的目录。如何做呢 ?为什么 exists() 返回 true 而我得到 404 呢?实际上我的设置/代码失败是什么?

任何帮助表示赞赏!

解决方案

根据@Namoshek 的回答,这是我所做的(供记录):

在上述控制器中,我只是检查了用户是否有权下载文件A。如果是这样,那么我返回一个视图,该视图具有指向名为downloadFileA 的路由的链接,该路由指向仍在上述同一个控制器中的函数downloadFileA

最后在downloadFileA函数中,我在检查用户是否有权下载文件后返回\Storage::disk('private')->download('fileA')。所以我检查了两次,但这不是问题,因为流量非常低(一周一次左右)。

【问题讨论】:

    标签: laravel laravel-5 laravel-5.7


    【解决方案1】:

    您可以使用Storage::download('filename.xyz') 而不是使用Storage::url('filename.xyu') 生成URL。这会将文件作为响应的内容发送。不过,对于大文件来说,它可能会占用大量资源。

    【讨论】:

    • 谢谢@Namoshek!我根据您的回答使用我使用的解决方案更新了我的问题。
    • 注意您在解决方案So I check twice but that's not a problem because there is very low traffic (once a week or so) 中的评论:实际上需要您检查两次权限(至少从我从要求中得到的)。否则,有权查看或下载文件的用户可以简单地将链接发送给其他人。公平地说,这样的权限检查根本不会消耗大量资源。
    猜你喜欢
    • 2016-10-28
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 2018-12-19
    • 1970-01-01
    • 1970-01-01
    • 2021-04-07
    • 2017-09-12
    相关资源
    最近更新 更多