[英]How to make temporary link for a downloadable file
我正在制作一个临时下载链接的项目,以保护文件免受热链接...
我相信这是可能的..因为我们都知道许多文件共享站点“不想提及任何”......他们的文件链接已过期......
前任。
如果我从他们的网站下载一个文件,他们会提供一个直接链接来单击它,对吗? 但该链接将在几小时或几分钟后立即过期。
我怎么知道链接已过期? 如果一天后我在下载管理器上复制相同的链接,则无法下载相同的文件。
我已经在htaccess
实现了这htaccess
。
前任。
RewriteRule .*\.(rar|ZIP)$ http://domain.com [R,NC]
如果他们复制浏览器地址栏中的直接链接,他们将被重定向到http://domain.com
但是,如果他们复制下载管理器上的直接链接,就会下载该文件。
如果他们将链接发布到论坛网站、博客等任何其他网站,并要求读者将链接复制并粘贴到他们的下载管理器中,以便他们可以直接下载,该怎么办?
这是我想防止以保护我的文件的问题。 我正在 PHP 上执行此操作,但我无法弄清楚...
非常感激你的帮助。
链接到/downloads/abb76b3acbd954a05bea357144d614b4
,其中abb...是一个随机字符串,例如当前时间的加盐哈希。 当您为某人创建此链接时,请将随机字符串存储在数据库表中。 此表可能如下所示:
+----+-------------+----------------------------------+---------------------+---------------------+
| 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 |
+----+-------------+----------------------------------+---------------------+---------------------+
当您在/downloads/...
收到请求时,查找随机字符串并发回正确的文件。 如果created
时间戳太旧,请不要这样做。 使用 cronjob 清除旧的表行,或者不太理想,每次有人向/downloads/...
发出请求时都这样做。
使用一些这样的代码
$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;
将此添加到您的 .htaccess 文件中
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule fakefile.php(.*)$ orignalfile.php?$1 [L,QSA]
我想到的解决方案如下:如果您有表示文件的表,例如 FileModel,您可以在那里保存文件名、一些详细信息、大小、文件系统中文件的路径和唯一性,这可以是 md5 的结果,来自您根据某些文件详细信息为其选择的某些数据,例如:
$data[FileModel]['unique'] = md5(time() . $data[FileModel]['file']);
每次让某人下载您的文件之前,您检查表中是否有这样的唯一值,如果是这样,您让某人使用在 FileModel 中创建的 downloadFile 方法下载它,但就在此之前,您将新文件设为唯一以防止更多下载
$data[FileModel]['unique'] = md5(time() . $data[$this -> name]['file']);
$this -> FileModel-> save($data[$this -> name]);
$this -> FileModel -> downloadFile($data[$this -> name]);
如果您的数据库中没有这样的唯一值,那么您只会向用户显示有关超时链接的错误
$this -> setFlashError('link expired');
在这里,我为您提供了一个示例操作原型,您可以在控制器中开始使用它:
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'));
}
}
}
您还可以创建日期时间字段,例如,您可以将 1 天添加到当前日期并检查剩余时间是否已过期。
我发现的一个:
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);
我知道这个老问题,但我有办法在不使用数据库的情况下只下载文件 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.