Laravel文件下载一旦您下载并注销就不需要身份验证



我和我的团队遇到了一个奇怪的Laravel错误,在搜索了几个小时并尝试了各种修复程序后,我们找不到一个好的解决方案。我们已经在 laravel 5.7、5.8 中对此进行了测试,甚至更新到 laravel 6,看看它是否有帮助,我们得到了相同的结果。

问题:

我们实现了下载路由,因此可以轻松地从存储文件夹中下载文件。我们将这条路由包装在一些中间件后面,包括用户访问级别和身份验证中间件。一切似乎都很好,用户可以单击应用程序中的链接并轻松下载文件,您甚至可以直接将链接放在URL中以下载文件。当我们测试不需要登录即可下载文件时,出现了这个问题。我们已将问题追踪到下面概述的特定路径。

  1. 登录到应用程序。(在登录之前,您无法通过将文件放入浏览器中来下载文件,请像我们预期的那样获取403(
  2. 下载您想要的任何文件,我们将下载的特定文件称为"File#1"。
  3. 注销应用程序。
  4. 在这一点上,不应该有身份验证。您无法访问不是在上一个会话中下载的任何页面或任何文件。然而。。。如果您尝试放置刚刚下载的文件之一的路径,例如"File#1"..文件将下载到客户端,即使它应该有身份验证。这似乎身份验证以某种方式保存到下载本身并跳过所有身份验证。在按预期登录到应用程序之前,无法下载任何其他未下载的文件。

代码如下:

注销方法:

public function logout(Request $request)
{
$this->guard()->logout();
$request->session()->flush();
return redirect('/');
}

路线:

Route::get('/download/{file}', array(
'as' => 'download',
'uses' => 'GeneratePDFController@download'
))->where('file', '.*')->middleware('auth');

中间件:

public function handle($request, Closure $next)
{
abort(403, 'Unauthorized action.');
if (!Auth::check()) {
abort(403, 'Unauthorized action.');
}
return $next($request);
}

下载控制器:

public function download($file)
{   
return response()->download(storage_path('app/public/' . $file));
}

如果我们清除浏览器上的缓存,它会解决问题,直到您登录并下载新文件。此外,注销后,您将完全阻止所有其他路由(即使是只需要身份验证的路由(,直到您重新登录。以前下载的文件似乎是唯一违反此规则的东西。我们的文件名足够复杂,这不是一个重大的安全风险,因为它们仅适用于当前用户会话,但我不习惯保留这种行为。

有什么想法吗?提前感谢大家,我会尽量跟上,以防有人回应。

您应该能够在下载时设置"不要缓存我!"标头:

return response()
->withHeaders([
'Cache-Control' => 'no-cache, no-store, must-revalidate',
'Pragma' => 'no-cache',
'Expires' => '0'
])
->download(storage_path('app/public/' . $file));

最新更新