Php 具有热链接保护和低内存使用率的Laravel下载响应

Php 具有热链接保护和低内存使用率的Laravel下载响应,php,laravel,nginx,download,hotlinking,Php,Laravel,Nginx,Download,Hotlinking,我有一个文件下载网站,我通过Laravel为文件提供热链接保护,但下载似乎让我的php进程保持了很长一段时间(因为一些用户的下载速度很差) 对于热链接保护,我在用户进入下载页面时创建一个会话,并在单击下载按钮时检查会话 有没有办法保护热链接,或者我可以降低内存使用率 这是触发下载的代码: if($request->session()->get('file') == $apk->generated_filename) { $head

我有一个文件下载网站,我通过Laravel为文件提供热链接保护,但下载似乎让我的php进程保持了很长一段时间(因为一些用户的下载速度很差)

对于热链接保护,我在用户进入下载页面时创建一个会话,并在单击下载按钮时检查会话

有没有办法保护热链接,或者我可以降低内存使用率

这是触发下载的代码:

if($request->session()->get('file') == $apk->generated_filename) 
        {   
            $headers = array
            (
                'Content-Type' => 'application/vnd.android.package-archive'
            );
            Apk::find($apk->id)->increment('downloads_co');
            return response()->download(config('custom.storage') . $apk->generated_filename, $apk->filename, $headers);
        }

您可以使用.htaccess进行访问

您可以使用此代码,也可以使用以下代码并自行调整

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourdomain.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]
参考资料:

使用
X-Accel-Redirect
内部
位置

绝对最好的方法是在nginx端使用,并使用上游端的HTTP响应头字段
X-Accel-Redirect
进行响应,以便nginx处理

除非被等人阻止,否则nginx对上游HTTP响应头执行特殊处理
X-Accel-Redirect
(您应该对标有
内部
指令的
位置
执行此操作,以确保直接访问此类文件的唯一可能方式是通过此类内部重定向)


这里的想法是,您的PHP脚本仍然可以以您认为必要的任何方式处理身份验证和热链接保护—用户身份验证、链接过期、基于个人AI的黑名单等等—但在一天结束时,一旦脚本完成,将以最高效的方式将文件实际馈送到客户端直接通过nginx实现


(请注意,使用
internal
关键字是非常重要的-它确保了在由于任何原因中断下载后,恢复下载的唯一方法是首先与您的PHP脚本联系。因此,使用nginx食谱中的这一聪明且经验证的技巧,您将获得两个方面的最佳效果-完全控制t链接和最佳资源利用率。)

您应该按缓冲区大小(例如2k)读取文件,然后发送响应,不要一次发送整个响应,编写如下脚本以下载文件:

    ignore_user_abort(true);
    set_time_limit(0); \

    $path = "/absolute_path_to_your_files/"; // change the path to fit your websites document structure

    $dl_file = preg_replace("([^\w\s\d\-_~,;:\[\]\(\).]|[\.]{2,})", '', $_GET['download_file']); // simple file name validation
    $dl_file = filter_var($dl_file, FILTER_SANITIZE_URL); // Remove (more) invalid characters
    $fullPath = $path.$dl_file;

    if ($fd = fopen ($fullPath, "r")) {
        $fsize = filesize($fullPath);
        $path_parts = pathinfo($fullPath);
        $ext = strtolower($path_parts["extension"]);
        switch ($ext) {
            case "pdf":
                header("Content-type: application/pdf");
                header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a file download
                break;
            // add more headers for other content types here
            default;
                header("Content-type: application/octet-stream");
                header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
                break;
        }
        header("Content-length: $fsize");
        header("Cache-control: private"); //use this to open files directly
        while(!feof($fd)) {
            $buffer = fread($fd, 2048);
            echo $buffer;
        }
    }
    fclose ($fd);

简单的黑客攻击是禁用来自cpanel本身的热链接。如果您没有下载文件的特殊情况。我没有使用cpanel或任何其他管理面板。下载文件需要用户身份验证吗?还是您只想防止热链接?只需使用Cloudflare热链接保护,不要在热链接上浪费资源。要在内存和热链接保护方面都取得成功,没有简单的方法。我建议将这些文件存储在CDN或其他云存储(如S3)中,并按照@Payam的建议将其放在Cloudflare之后,这样做可以将响应重定向到以下重定向::($url)不幸的是,我使用的是nginx而不是apache。请编辑您的问题,因为这是一个完美的答案^^
    ignore_user_abort(true);
    set_time_limit(0); \

    $path = "/absolute_path_to_your_files/"; // change the path to fit your websites document structure

    $dl_file = preg_replace("([^\w\s\d\-_~,;:\[\]\(\).]|[\.]{2,})", '', $_GET['download_file']); // simple file name validation
    $dl_file = filter_var($dl_file, FILTER_SANITIZE_URL); // Remove (more) invalid characters
    $fullPath = $path.$dl_file;

    if ($fd = fopen ($fullPath, "r")) {
        $fsize = filesize($fullPath);
        $path_parts = pathinfo($fullPath);
        $ext = strtolower($path_parts["extension"]);
        switch ($ext) {
            case "pdf":
                header("Content-type: application/pdf");
                header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a file download
                break;
            // add more headers for other content types here
            default;
                header("Content-type: application/octet-stream");
                header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
                break;
        }
        header("Content-length: $fsize");
        header("Cache-control: private"); //use this to open files directly
        while(!feof($fd)) {
            $buffer = fread($fd, 2048);
            echo $buffer;
        }
    }
    fclose ($fd);