【发布时间】:2019-04-24 16:04:31
【问题描述】:
我正在努力为用户提供一个他们可以在登录后下载的文件的链接。我阅读了this 和that (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