Use a cookie to validate the download link. If the two match, then allow the download.
For example, the PHP file containing the download link could generate it as follows:
<?php
///// Put these two lines in a shared config file: /////
define('SALT','*** Insert a random string here ***');
define('RESOURCES_DIRECTORY', '/home/eazy/files/');
////////////////////////////////////////////////////////
function get_download_url($filename) {
$expire = time() + 3600; // Link expires in 1 hour
$auth_data = "f=$filename&e=$expire";
$cookie_key = md5($auth_data . SALT);
setcookie('key',$cookie_key,0,'/');
return "/download.php?$auth_data";
}
?>
<a href="<?= get_download_url('my_video.mp4') ?>" rel="nofollow">Download video</a>
And then the /download.php
file can authenticate the download as follows:
<?php
$filename = @$_GET['f'];
$expire = intval(@$_GET['e']);
$auth_data = "f=$filename&e=$expire";
$cookie_key = md5($auth_data . SALT);
$file = RESOURCES_DIRECTORY . $filename;
if (@$_COOKIE['key'] != $cookie_key || $expire < time() || !file_exists($file)) {
header('HTTP/1.1 404 Not Found');
die("File not found");
}
else {
header('Content-Type: video/mp4');
header('Content-Length: ' . filesize($file));
readfile($file);
}
If you can avoid generating open_basedir restriction errors, store the downloadable files outside your WWW directory. That way, users will have no choice but to use this script to access the files, and will only be successful if they have obtained a valid cookie by visiting the page containing the download link.
Note: this code will defeat casual link-sharing, but isn't super-secure and won't stop people sharing the downloaded files. There's no point being too paranoid, because people will still be able to share the downloaded files even if they can't easily share the download links.