简体   繁体   English

如何为可下载文件制作临时链接

[英]How to make temporary link for a downloadable file

I am making a project for a temporary download link for me to protect the file from hotlinkers...我正在制作一个临时下载链接的项目,以保护文件免受热链接...

I believe that this is possible to do so.. because we all know that many of file sharing site " don't wanna mention any "... their link for the file has expiration...我相信这是可能的..因为我们都知道许多文件共享站点“不想提及任何”......他们的文件链接已过期......

Ex.前任。

If I download one file from their site they give a direct link to click it right?如果我从他们的网站下载一个文件,他们会提供一个直接链接来单击它,对吗? but then that link will expire right after a few hours or minutes.但该链接将在几小时或几分钟后立即过期。

How should I know that the link was expired?我怎么知道链接已过期? If I copy the same link on my download manager after one day, it can't download the same file.如果一天后我在下载管理器上复制相同的链接,则无法下载相同的文件。

I already made this possible in htaccess .我已经在htaccess实现了这htaccess

Ex.前任。

RewriteRule .*\.(rar|ZIP)$ http://domain.com [R,NC]

if they copy the direct link in the address bar of the browser they will be redirected in http://domain.com如果他们复制浏览器地址栏中的直接链接,他们将被重定向到http://domain.com

But then if they copy the direct link on their download manager the file will be downloaded.但是,如果他们复制下载管理器上的直接链接,就会下载该文件。

What if they post the link into any other site like forum website, blog, etc., and ask the reader to copy and paste the link into their download manager, so that they can download it directly.如果他们将链接发布到论坛网站、博客等任何其他网站,并要求读者将链接复制并粘贴到他们的下载管理器中,以便他们可以直接下载,该怎么办?

This is the problem I want to prevent to protect my file.这是我想防止以保护我的文件的问题。 I am doing this on PHP but I can't figure it out...我正在 PHP 上执行此操作,但我无法弄清楚...

Your help is very much appreciated.非常感激你的帮助。

Link to something like /downloads/abb76b3acbd954a05bea357144d614b4 , where abb... is a random string such as a salted hash of the current time.链接到/downloads/abb76b3acbd954a05bea357144d614b4 ,其中abb...是一个随机字符串,例如当前时间的加盐哈希。 When you make this link for someone, store the random string in a database table.当您为某人创建此链接时,请将随机字符串存储在数据库表中。 This table might look like:此表可能如下所示:

+----+-------------+----------------------------------+---------------------+---------------------+
| id | filename    | token                            | created             | modified            |
+----+-------------+----------------------------------+---------------------+---------------------+
|  1 | image.jpg   | abb76b3acbd954a05bea357144d614b4 | 2012-03-26 19:36:41 | 2012-03-26 19:36:41 |
|  2 | program.exe | 19660d0f5e0ca3d42e1718de5d0a1d7e | 2012-08-29 11:07:58 | 2012-08-29 11:07:58 |
+----+-------------+----------------------------------+---------------------+---------------------+

When you get a request at /downloads/... , look up the random string and send back the correct file.当您在/downloads/...收到请求时,查找随机字符串并发回正确的文件。 If the created timestamp is too old, don't do so.如果created时间戳太旧,请不要这样做。 Use a cronjob to clean out old table rows, or less ideally, do this every time someone makes a request to /downloads/... .使用 cronjob 清除旧的表行,或者不太理想,每次有人向/downloads/...发出请求时都这样做。

Use some code like this使用一些这样的代码

 $path="uploads/";
                  $actualfilename=$path.$filename;
                  $fakefilename="downloadfile.pdf";
                   if($typeofview=="download") {
                          @readfile($actualfilename);
                        header('Content-type: application/pdf');
                        header('Content-Disposition: attachment; filename="' . $fakefilename . '"');
                        header('Content-Transfer-Encoding: binary');
                        header('Content-Length: ' . filesize($actualfilename));
                        header('Accept-Ranges: bytes');
                        exit;

add this to your .htaccess file将此添加到您的 .htaccess 文件中

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule fakefile.php(.*)$ orignalfile.php?$1 [L,QSA]

The solution that comes to my mind is as follows: If you have table which represent file and for example FileModel you can save there name of the file, some details, size, also path to the file in your file system and unique, which can be result of md5 from some of data you choose for it based on some file details for example :我想到的解决方案如下:如果您有表示文件的表,例如 FileModel,您可以在那里保存文件名、一些详细信息、大小、文件系统中文件的路径和唯一性,这可以是 md5 的结果,来自您根据某些文件详细信息为其选择的某些数据,例如:

$data[FileModel]['unique'] = md5(time() . $data[FileModel]['file']);

Each time before letting someone download your file you check if there is such unique value in your table if so you let someone download it with ur downloadFile method created in FileModel, but just before that you make new unique to prevent from any more downloads每次让某人下载您的文件之前,您检查表中是否有这样的唯一值,如果是这样,您让某人使用在 FileModel 中创建的 downloadFile 方法下载它,但就在此之前,您将新文件设为唯一以防止更多下载

$data[FileModel]['unique'] = md5(time() . $data[$this -> name]['file']);
$this -> FileModel-> save($data[$this -> name]);
$this -> FileModel -> downloadFile($data[$this -> name]);

If there is no such unique value in ur database then you just show an error about timeouted link to the user如果您的数据库中没有这样的唯一值,那么您只会向用户显示有关超时链接的错误

$this -> setFlashError('link expired');

Here I pase for you an example prototype of action which you can start with in your controller:在这里,我为您提供了一个示例操作原型,您可以在控制器中开始使用它:

function download($file_data = ''){
        $data = $this->FileModel->find('first', array('conditions' => array('FileModel.unique' => $file), 'fields' => array('*')));

        if(!is_array($data[FileModel])) $this -> setFlashError('link expired');

        else
        {
            $data[FileModel]['unique'] = md5(time() . $data[$this -> name]['file']);
            $this -> FileModel-> save($data[$this -> name]);
            if(!$this -> FileModel -> downloadFile($data[$this -> name]))
            {
                $this -> setFlashError('error'));
            }
        }
}

Also you can create datetime field where you can for example add 1 day to current date and check wheter time left to download it expired.您还可以创建日期时间字段,例如,您可以将 1 天添加到当前日期并检查剩余时间是否已过期。

the one i have found:我发现的一个:

header('Content-Type: application/force-download');
$filee = "your_file.txt";
$filesLocation = dirname(__file__).'/the_sub_folder_for_the_file/'.$filee;
header('Content-Length:' . filesize($filesLocation));
header("Content-Disposition: inline; filename=\"".$filee."\"");
$filesPointer = fopen($filesLocation,"rb");
fpassthru($filesPointer);

i know this old question but i have way to download the file just 1 time without use database , fast way :)我知道这个老问题,但我有办法在不使用数据库的情况下只下载文件 1 次,快速的方法:)

if( isset($_GET['file']) && file_exists($_GET['file']) )
{
    $oldName = $_GET['file'];
    $newName = md5(time()).".txt";

    if( rename($oldName, $newName) ) { // rename file to download just once
        downloadFile( $newName ); // download file function
    } else {
        echo 'this file is not exist';
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM