拒绝通过 URL 从网络服务器直接下载文件
Posted
技术标签:
【中文标题】拒绝通过 URL 从网络服务器直接下载文件【英文标题】:Deny direct file download from webserver by URL 【发布时间】:2021-11-16 14:54:32 【问题描述】:我有一个网站,用户可以登录并由 sessions 和 $user[id]
标识。他们可以上传文件。文件存储在 htdocs/uploads 中。每个文件数据都存储在一个表中,以便在文件名、位置和 user_id 之间建立链接。在我网站的某些地方,我可以通过以下方式下载文件:<a href="' . $row['path'] . '" target="_blank" download>Download file</a>
。
在$row['path']
后面给出了一个类似 domain.com/uploads/filename.jpg 的 URL。如果用户知道这个 URL 路径,他也可以通过在浏览器中输入 URL 来下载文件而无需登录或识别。我想避免这种情况。我如何确保通过点击我网站上的此类下载链接,只能从 htdocs/uploads 下载文件。
=> 我无法在 htdocs 之外创建文件夹 => 我试图更改文件夹权限,但没有成功 => 我的网站基本上是用 php 做的,首选 PHP 的解决方案。
有什么想法/帮助吗?谢谢!
【问题讨论】:
您可以创建一个文件服务代理,在.htaccess
文件中,您可以使用Rewrite
规则将请求重定向到您的代理,该代理将首先检查用户会话。这可能会对您有所帮助:medium.com/@ignasposka/…
【参考方案1】:
您将需要沿着让 PHP 为您提供文件的途径。这将确保您可以在提供文件之前验证用户凭据。
参见 php.net here 上的示例。这将解释如何使用header()
从 PHP 提供文件。这个answer 还概述了一些关键概念。
完成此操作后,您可以使用htaccess rules 拒绝直接访问这些文件。这将确保用户只能通过 php 端点访问文件,并且这些端点可以执行用户凭据的验证。
【讨论】:
谢谢。这对我来说是正确的提示。请参阅下面的解决方案。【参考方案2】:我已经通过以下方式解决了这个问题:
-
在我的文件夹 htdocs/uploads 中添加了一个 .htaccess 文件,其中包含以下内容:
<FilesMatch ".*">
Order Allow,Deny
Deny from All
</FilesMatch>
-
创建了一个文件:file_download.php,内容如下:
// Doing here some user verification based on the session and user_id
if($user['id'] != 'something i want to be')
die('Not allowed to download this file');
else
// Verify the download as requested
// Basic file name
$file = basename($_GET['file']);
// Path where the file should be stored
$file = 'uploads/'.$file;
if(!file_exists($file)) // file does not exist
die(''.$file.' file not found');
else
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$file");
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: binary");
// read the file from disk
readfile($file);
-
将下载链接从
<a href="' . $row['path'] . '" target="_blank" download>Download file</a>
更改为<a href="file_download.php?file=<?= $row['path'] ?>Download</a>
这种方式会阻止任何尝试通过在浏览器中使用明确的 URL 来下载文件。只有拥有用户标识和我的网站提供的链接,才能下载该文件。如果有人不需要用户验证,只需删除file_download.php
中的第一个if/else
即可。
【讨论】:
以上是关于拒绝通过 URL 从网络服务器直接下载文件的主要内容,如果未能解决你的问题,请参考以下文章