我正在尝试更改下载文件的路径,以便通过添加不存在的文件夹“ / protected /”来保持受保护的状态
我的真实路径是
“ / var / www / html / var / uploads / Statements / 2019-06 / export-1.csv”
最后,我需要这样:
“ http://app.local:8080/protected/uploads/Statements/2019-06/export-1.csv”
我尝试了各种版本,但是我的代码未返回所需路径。
可以帮助编辑我的代码:
$file = realpath($file);
$projectDir = $this->container->get('kernel')->getProjectDir();
$webDir = realpath($projectDir);
$finalPath = substr($file, strlen($webDir));
$request = $this->container->get('request_stack')->getCurrentRequest();
$downloadUrl = $request->getScheme() . '://' . $request->getHttpHost() . $request->getBasePath() . '/' . $finalPath;
return $downloadUrl;
$ downloadUrl可以正常工作,但是$ finalPath格式不正确。
答案 0 :(得分:1)
您应该将上传文件而不是保存在public/
文件夹中,而应将其保存在Web服务器公共文档根目录之外的某个位置,因为这存在潜在的安全风险,即有人可能不通过该机制就可以获取它们。例如,您可以在public/
旁边有一个名为data/uploads
的目录。这样可以确保Web服务器无法访问文件。
在您的Symfony项目中,您可以创建一个DownloadController,将路径或文件名作为参数,然后将其附加到文件夹中:
class DownloadController extends AbstractController
{
// This should be the path you store your files in
private $uploadDir;
public function __construct(string $uploadDir)
{
$this->uploadDir = $uploadDir;
}
/**
* @Route("/protected/uploads/{file}", name="download", requirements={"file"=".+"})
*/
public function index(string $file)
{
return new BinaryFileResponse($this->uploadDir . $file);
}
}
请参阅:https://symfony.com/doc/current/routing/slash_in_parameter.html和https://symfony.com/doc/current/components/http_foundation.html#serving-files
您可能需要进行一些清理和健全性检查,例如当文件丢失或有人想诱使您下载基本目录之外的内容时,大致应该是这样。
现在,您无需调用伪链接,而只需在应用程序中调用例如在您的模板中:
{{ path('download', { 'file': 'Statements/2019-06/export-1.csv' }) }}
这将在您的应用程序内创建一个正确的下载链接。您还可以根据虚拟文件名创建映射,例如该控制器操作中实际文件名的哈希值。您只需要以某种方式跟踪引用即可。您还可以添加访问检查,或下载该操作的计数器。
回顾一下,假设您的项目位于/var/www/myproject
中,则Web服务器的公用目录为/var/www/myproject/public/
,而文件则保留在/var/www/myproject/data/uploads/
中。然后,上载的文件位于/var/www/myproject/data/uploads/Statements/2019-06/export-1.csv
中,URL如下所示:http://app.local:8080/protected/uploads/Statements/2019-06/export-1.csv
。通过更改路线注释的路径,您可以简单地调整URL,而无需移动单个文件。