如何限制未登录用户通过ViewerJS URL访问服务器文件?
解决未登录用户绕过ViewerJS直接访问上传文件的问题
看起来你踩了个常见的坑:ViewerJS是直接让浏览器请求了uploads目录下的静态文件,这个请求根本没经过你定义的ViewerJS/*路由。因为你的F3路由只拦截针对ViewerJS/路径的请求,但文件URL是../uploads/2138970950.pdf,浏览器会直接向这个路径发请求,完全绕开了你的路由校验。
下面给你几个可靠的解决方案,按推荐程度排序:
方案1:将uploads目录移出Web根,通过F3路由代理文件访问
这是最安全的做法,彻底断绝直接访问文件的可能:
- 调整文件目录结构:把
uploads文件夹从gbdportal-new/(Web根目录)移到Web根外面,比如和gbdportal-new同级的位置,这样外部无法直接通过URL访问到它。 - 添加F3路由校验登录:定义一个专门的路由来处理文件请求,先验证用户登录状态,再返回文件内容:
$f3->route('GET /secure-files/@filename', function($f3) { // 这里替换成你的登录校验逻辑,比如检查session中的用户标识 if (!isset($_SESSION['logged_in_user']) || $_SESSION['logged_in_user'] !== true) { $f3->error(403, "请先登录以访问该文件"); return; } // 安全处理文件名,防止路径遍历攻击(关键!) $safeFilename = basename($f3->get('PARAMS.filename')); $filePath = '../uploads/' . $safeFilename; // 这里是你移出Web根后的uploads路径 // 检查文件是否存在且是合法文件 if (!file_exists($filePath) || !is_file($filePath)) { $f3->error(404, "文件不存在"); return; } // 设置正确的HTTP头,让浏览器正确解析文件 $mime = mime_content_type($filePath); header("Content-Type: $mime"); header("Content-Length: " . filesize($filePath)); // 输出文件内容 readfile($filePath); });
- 修改ViewerJS的访问路径:把原来的
../uploads/2138970950.pdf改成/secure-files/2138970950.pdf,最终ViewerJS的URL变成:http://localhost/gbdportal-new/ViewerJS/#/secure-files/2138970950.pdf
这样所有文件请求都会经过F3的路由校验,未登录用户会直接收到403禁止访问的响应。
方案2:用服务器配置(Apache/Nginx)拦截uploads请求到F3
如果不想移动uploads目录,可以通过Web服务器的重写规则,把所有对uploads的请求转发到F3的入口文件,再由F3做登录校验:
如果你用Apache(.htaccess)
在gbdportal-new/目录下的.htaccess中添加:
RewriteEngine On # 拦截uploads的请求,转发到index.php处理 RewriteRule ^uploads/(.*)$ index.php?file=uploads/$1 [L]
然后在F3的入口文件中处理file参数,逻辑和方案1类似:校验登录→检查文件合法性→返回内容。
如果你用Nginx
在站点配置中添加:
location /uploads/ { rewrite ^/uploads/(.*)$ /index.php?file=uploads/$1 last; }
同样在F3中处理file参数即可。
方案3:修改ViewerJS的文件加载逻辑(不推荐)
ViewerJS本身是前端工具,默认直接访问文件URL。你可以修改它的源码,让它通过你的后端接口获取文件二进制内容,再进行渲染。但这个方案需要深入ViewerJS的代码,维护成本高,除非你有特殊需求,否则不建议用。
关键安全提醒
- 无论用哪个方案,一定要处理文件名的安全性:用
basename()或者F3的$f3->clean()方法过滤文件名,防止用户构造../../etc/passwd这样的路径进行遍历攻击。 - 登录校验逻辑要严谨:确保session没有被伪造,比如用F3的内置session机制而非自己手写。
内容的提问来源于stack exchange,提问作者Azima
相关产品推荐
相关产品推荐

