下载后过期的临时URL

时间:2013-04-21 18:00:41

标签: java php download

我想为我正在开发的Java游戏创建一个启动程序,要求用户在下载游戏之前登录。我的想法是让启动器将凭据发送到我的网络服务器,如果凭据正确,网络服务器将输出临时文件的位置。然而,鉴于以下情况,这将有点棘手/低效:

  1. 每次有人更新时,服务器都需要复制游戏文件,
  2. 网络服务器不知道文件何时下载完毕。
  3. 也许启动程序可以向单独的脚本发送请求以删除给定临时名称的文件?问题在于,可以轻松地对启动器进行反编译和修改,以便不发送请求,从而无法创建新文件。

    关于这个想法及其问题的任何建议?

3 个答案:

答案 0 :(得分:3)

我会使用数据库,如下所示:

urlgenerator.php

 <?php

 // generate code
 $code = uniqid();

 // save code to database
 db_save($code);

 // write link
 echo '<a href="download.php?code=' . $code . '">Download</a>';

的download.php

<?php

// get code from url
$single_use_code = $_GET['code'];

// check if the code is in the db
if(db_get_code($single_use_code)) {
   // remove code from database as it is single use only
   db_remove($single_use_code);
   // start download
   start_download();
} else {
   // the code is not valid
   die('BAD code');
}

答案 1 :(得分:1)

尝试这样的事情:

// Define a random key
$key = 'kgjiowtjiohgjiut09ig90im09yig90mi903i490ti209tgwgt';  
$secondsValid = 300;

if($_GET['action'] == 'download')
{
  $time = $_GET['time'];
  if(time() - $time > $secondsValid)
    die('Code has expired, please try again');
  if($_GET['validation'] != md5($time.$key))
    die('Invalid validation code');
  DownloadFile();
  die;
}
elseif(CredentialsAreCorrect())
{
  $time = time();
  header('Location: '.$_SERVER['REQUEST_URI'].'?action=download&time='.$time.'&validation='.md5($time.$key));
  die;
}
else
  die('Invalid credentials');

这是一种简单的方法,可以为经过验证的用户提供一个带时间戳的URL(在这种情况下有效5分钟),不需要任何讨厌的复制/符号链接/任何涉及的内容,没有数据库,只需使用不能被黑客入侵的基本设施钥匙是安全的。只要确保你的密钥有足够的熵(40多个随机按键应该这样做),所以没有彩虹表或暴力攻击是可行的。

答案 2 :(得分:0)

简单的解决方法:在unix系统上,您可以在文件正在使用时删除该文件,而不会影响该文件上当前打开的文件句柄。所以

  1. 用户请求下载
  2. 脚本在documentmentroot中的某个地方创建一个符号链接,指向文件存储的任何位置(文档根目录之外的某处)
  3. 符号链接的URL作为参数发送给用户。
  4. 用户点击donwload链接,例如http://example.com?get=path/of/symlink
  5. 下载脚本fopen()是符号链接,并开始抛出文件的内容
  6. 脚本删除符号链接后fopen()'d
  7. 现在符号链接已经消失,不能再重复使用了,但是下载脚本仍然会向用户发送数据,因为它在删除之前打开了符号链接/文件。