Laravel 5.7 :storage/app/private 上的 404 或 403 而它在 storage/app/public 上有效
Laravel 5.7 : 404 or 403 on storage/app/private whereas it works on storage/app/public
我正在努力为用户提供一个 link 文件,他们可以在登录后下载该文件。我读过 this and 。
所以在我的 app/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
但是在视图中,当我点击 link http://127.0.0.1:8000/storage/private/A/fileA.tar.gz
我得到 404 尽管 exists
函数 returns true
.
所以我尝试在 /config/filesystems.php 中定义一个直接 "short-cut" 到我的 "private" 文件夹:
'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
但是现在当我点击生成的 link http://localhost/privateDownload/A/fileA.tar.gz
时我得到 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/
没有问题,可以下载文件。这没什么意思,因为我想防止在未登录的情况下下载此文件。
根据 doc 和其他 SO 答案,似乎可以访问与 public
不同的目录。如何做呢 ?为什么 exists()
return 是真的,而我得到的是 404?我的设置/代码失败实际上是什么?
感谢任何帮助!
解决方案
根据@Namoshek 的回答,这是我所做的(作为记录):
在前面提到的控制器中,我只是检查了用户是否有权下载fileA。如果是这样,那么我 return 一个视图有一个 link 到一个名为 downloadFileA
的路由,该路由指向一个函数 downloadFileA
仍然在同一个上述控制器中。
最后在函数 downloadFileA
I return \Storage::disk('private')->download('fileA')
检查用户是否有权下载文件后。所以我检查了两次,但这不是问题,因为流量非常低(每周一次左右)。
您可以使用 Storage::download('filename.xyz')
而不是使用 Storage::url('filename.xyu')
生成 URL。这会将文件作为响应的内容发送。不过,对于大文件来说,它可能是资源密集型的。
我正在努力为用户提供一个 link 文件,他们可以在登录后下载该文件。我读过 this and
所以在我的 app/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
但是在视图中,当我点击 link http://127.0.0.1:8000/storage/private/A/fileA.tar.gz
我得到 404 尽管 exists
函数 returns true
.
所以我尝试在 /config/filesystems.php 中定义一个直接 "short-cut" 到我的 "private" 文件夹:
'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
但是现在当我点击生成的 link http://localhost/privateDownload/A/fileA.tar.gz
时我得到 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/
没有问题,可以下载文件。这没什么意思,因为我想防止在未登录的情况下下载此文件。
根据 doc 和其他 SO 答案,似乎可以访问与 public
不同的目录。如何做呢 ?为什么 exists()
return 是真的,而我得到的是 404?我的设置/代码失败实际上是什么?
感谢任何帮助!
解决方案
根据@Namoshek 的回答,这是我所做的(作为记录):
在前面提到的控制器中,我只是检查了用户是否有权下载fileA。如果是这样,那么我 return 一个视图有一个 link 到一个名为 downloadFileA
的路由,该路由指向一个函数 downloadFileA
仍然在同一个上述控制器中。
最后在函数 downloadFileA
I return \Storage::disk('private')->download('fileA')
检查用户是否有权下载文件后。所以我检查了两次,但这不是问题,因为流量非常低(每周一次左右)。
您可以使用 Storage::download('filename.xyz')
而不是使用 Storage::url('filename.xyu')
生成 URL。这会将文件作为响应的内容发送。不过,对于大文件来说,它可能是资源密集型的。