简体   繁体   中英

Temporary URLs that expire after download

I'd like to create a launcher for a Java game I'm developing that will require the user to log in before the game itself can be downloaded. My idea was to have the launcher send the credentials to my webserver, and the webserver would output the location of a temporary file given the credentials were correct. However, this would be a bit tricky/inefficient, given:

  1. The server would need to copy the game file every time someone updates, and
  2. The webserver wouldn't know when the file was finished downloading.

Perhaps the launcher could send a request to a separate script to delete a file of the given temporary name? The problem with that is that the launcher could easily be decompiled and modified to not send the request, defeating the purpose of creating a new file.

Any suggestions as to this idea and its issues?

I would use a database, like this:

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

Try something like this:

// 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');

This is an easy way to give a validated user a timebombed URL (valid for 5 minutes in this case) without any nasty copying/symlinking/whatever involved, no databases, just using basic facilities that cannot be hacked as long as the key is secure. Just make sure your key has enough entropy (40+ random keypresses should do it) so no rainbow table or brute force attack is feasible.

Simple workaround: on a unix system, you can remove a file while it's in use without affecting currently-open file handles on that file. so

  1. user requests download
  2. script makes a symlink in the documentroot somewhere that points at wherever the file is really stored (somewhere outside of the document root)
  3. URL to the symlink is send out as a parameter to the user.
  4. User clicks on the donwload link, eg http://example.com?get=path/of/symlink
  5. The download script fopen()'s the symlink and starts dishing out the file's contents
  6. script REMOVES the symlink after it's been fopen()'d

Now the symlink is gone and can't be reused anymore, but the download script will still be sending data to the user because it opened the symlink/file before it was removed.

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