如何编写HTACCESS规则将指定文件夹下的所有文件请求转发至PHP校验页面并携带查询参数
如何编写HTACCESS规则将指定文件夹下的所有文件请求转发至PHP校验页面并携带查询参数
我来帮你搞定这个需求!核心思路是用.htaccess把所有指向customers文件夹下的文件请求,重写到你的check.php脚本,同时把请求的文件路径和token参数传递过去,由PHP来处理权限校验和文件流输出。
一、编写data目录下的.htaccess规则
首先,在你的example.com/data/目录下创建或修改.htaccess文件,添加以下规则:
# 启用Apache重写引擎(必须开启,否则规则无效) RewriteEngine On # 排除对check.php本身的请求,避免无限循环重写 RewriteCond %{REQUEST_URI} !/data/check\.php$ [NC] # 确保请求的是实际存在的文件(可选,但能过滤掉对不存在文件的无效请求) RewriteCond %{REQUEST_FILENAME} -f # 把customers文件夹下的所有文件请求转发到check.php,携带文件路径和原token参数 RewriteRule ^customers/(.*)$ check.php?file=customers/$1 [L,QSA]
规则解释:
RewriteEngine On:开启Apache的URL重写模块,这是所有重写规则的前提(如果你的服务器没开启mod_rewrite,需要先在Apache配置里启用)。- 排除
check.php的规则:如果不加上这条,当check.php被请求时也会被重写,导致无限循环。 %{REQUEST_FILENAME} -f:只对实际存在的文件生效,避免把不存在的文件请求也转发给PHP,减少无效请求。RewriteRule的QSA标志:会自动把原请求的查询参数(比如token=1234)追加到新的URL上,这样check.php就能直接拿到token参数,不用手动拼接。[L]标志:表示这是最后一条规则,匹配到后就停止执行后续重写规则。
二、check.php的核心校验与文件输出逻辑
接下来你需要完善data/check.php的代码,处理token校验、文件安全检查和文件流输出。这里给你一个通用的示例框架,你可以根据自己的业务逻辑调整:
<?php // 1. 获取请求参数 $requestedFile = $_GET['file'] ?? ''; $userToken = $_GET['token'] ?? ''; // 2. 关键:防止路径遍历攻击(必须做,避免恶意用户访问服务器上的敏感文件) $allowedBaseDir = realpath(__DIR__ . '/customers'); $targetFile = realpath(__DIR__ . '/' . $requestedFile); // 验证目标文件是否在允许的customers目录范围内 if (!$targetFile || strpos($targetFile, $allowedBaseDir) !== 0) { http_response_code(403); echo "访问被拒绝:非法文件路径"; exit; } // 3. 验证token的合法性(这里替换成你自己的业务逻辑) // 示例:比如从数据库查询该文件对应的有效token,或者验证登录用户的权限 $isTokenValid = false; // 注意:下面只是模拟校验,实际要换成你的真实逻辑(比如查库、会话验证等) if ($userToken === '1234') { $isTokenValid = true; } if (!$isTokenValid) { http_response_code(403); echo "访问被拒绝:无效的Token"; exit; } // 4. 检查文件是否存在且可读 if (!file_exists($targetFile) || !is_readable($targetFile)) { http_response_code(404); echo "文件不存在或无法读取"; exit; } // 5. 设置正确的文件MIME类型,确保浏览器能正确渲染(比如PDF、图片、文本文件) $mimeType = mime_content_type($targetFile); header("Content-Type: $mimeType"); // 可选:如果想让用户下载文件而不是在线预览,取消下面这行注释 // header("Content-Disposition: attachment; filename=\"" . basename($targetFile) . "\""); // 6. 流式输出文件内容(高效输出大文件,不用一次性读取到内存) readfile($targetFile); exit;
代码关键点说明:
- 路径遍历防护:用
realpath把相对路径转换成绝对路径,再检查是否在允许的customers目录下,彻底杜绝../../etc/passwd这类恶意路径请求。 - Token校验:这里的示例是固定token,实际场景中你可以根据文件路径查询数据库中的有效共享token,或者验证当前登录用户的权限(比如只有文件所属用户才能访问)。
- MIME类型设置:
mime_content_type能自动识别文件类型,确保浏览器正确渲染PDF、图片等文件。 - 流式输出:
readfile是PHP输出文件最高效的方式,适合处理大文件,不会占用过多内存。
三、额外优化建议
- 禁止目录索引:在
.htaccess里加上Options -Indexes,防止用户直接访问customers目录看到所有文件列表。 - 处理目录请求:如果不想让用户访问
customers目录本身,可以在RewriteCond里加上RewriteCond %{REQUEST_FILENAME} !-d,排除对目录的请求。 - 断点续传支持:如果你的文件很大,可以添加对HTTP Range头的支持,让用户能断点续传下载(需要额外处理,可选)。
备注:内容来源于stack exchange,提问作者Devanshu Goyal
相关产品推荐
相关产品推荐

