You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何禁止通过直接访问URL下载Web服务器上传目录内的文件

解决方案整体思路

核心是通过PHP做下载权限校验层,同时屏蔽uploads目录的直接外部访问,所有下载请求都走PHP校验逻辑后再返回文件内容。


第一步:禁止直接访问uploads目录的文件

因为你无法将文件放到htdocs外、也无法修改目录权限,直接通过Web服务器配置屏蔽目录外部访问即可:

  • 如果你用的是Apache服务器,在htdocs/uploads目录下新建.htaccess文件,写入以下内容:
Deny from all
  • 如果你用的是Nginx服务器,在站点的Nginx配置文件中添加如下规则:
location ~* ^/uploads/ {
    deny all;
    return 403;
}

配置完成后,即使用户知道完整的文件URL,也会直接返回403拒绝访问。


第二步:开发PHP下载代理脚本

在站点根目录新建download.php文件,负责登录校验、权限校验、文件输出,参考代码如下:

<?php
session_start();
// 1. 先校验用户登录状态
if (!isset($_SESSION['user']['id'])) {
    http_response_code(403);
    die('无访问权限,请先登录');
}
$current_user_id = $_SESSION['user']['id'];

// 2. 校验传入的文件ID参数
if (empty($_GET['file_id']) || !is_numeric($_GET['file_id'])) {
    http_response_code(400);
    die('参数错误');
}
$file_id = intval($_GET['file_id']);

// 3. 从数据库查询文件信息,同时校验文件归属
// 此处替换为你自己的数据库连接和查询逻辑
$pdo = new PDO('mysql:host=你的数据库地址;dbname=你的库名', '数据库账号', '数据库密码');
$stmt = $pdo->prepare("SELECT filename, storage_path FROM 你的文件表名 WHERE id = ? AND user_id = ?");
$stmt->execute([$file_id, $current_user_id]);
$file_info = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$file_info) {
    http_response_code(404);
    die('文件不存在或你无权限访问该文件');
}

// 4. 拼接文件物理路径,校验文件是否真实存在
$physical_path = $_SERVER['DOCUMENT_ROOT'] . str_replace('你的站点域名/', '/', $file_info['storage_path']);
if (!file_exists($physical_path) || is_dir($physical_path)) {
    http_response_code(404);
    die('文件不存在');
}

// 5. 输出下载头,返回文件内容
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $file_info['filename'] . '"');
header('Content-Length: ' . filesize($physical_path));
// 清空缓冲区避免额外输出导致文件损坏
ob_clean();
flush();
readfile($physical_path);
exit;
?>

第三步:修改页面内的下载链接

把原来直接指向文件URL的下载链接,替换为指向代理脚本+文件ID的格式:
原代码:

<a href="' . $row['path'] . '" target="_blank" download>Download file</a>

修改后:

<a href="/download.php?file_id=' . $row['id'] . '" target="_blank" download>Download file</a>

其中$row['id']是你文件数据表对应的主键ID。


可选安全优化

  • 禁止在下载脚本中直接传递文件路径作为参数,避免路径遍历漏洞,所有路径必须通过文件ID从数据库查询获取
  • 可以额外增加CSRF Token校验,防止恶意链接诱导用户下载
  • 如果需要支持大文件下载,可以把readfile替换成分段读取输出的逻辑,避免占用过多内存

内容的提问来源于stack exchange,提问作者Mischa Mustermann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 18:18:02