简体   繁体   中英

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 .

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

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...

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. 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. If the created timestamp is too old, don't do so. Use a cronjob to clean out old table rows, or less ideally, do this every time someone makes a request to /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

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 :

$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

$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.

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 :)

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';
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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