Click to See Complete Forum and Search --> : Secure download


ricosushi
06-29-2006, 12:36 PM
Hi.

Im doing an virtual music song store and i want customers to download the purchased song.

But i dont know how to give the customer the song.mp3 without letting the link avaible for anyone.

In other words i want to be able to download the song only once.

Hope you can help me.

thanks.

themarty
06-29-2006, 06:45 PM
there's a lot of ways to do it. one would be:
- put all the mp3s in a special directory, that you protect with a .htaccess file (so no one can access anything in that directoy without the proper credentials)
- write a download script that reads the contents of the requested mp3 file (from the protected directory) and outputs it to the user

then, the only thing you need to do with the download script is
1) check whether the user is allowed to download
2) make it safe, so they won't be able to download anything other then those mp3-files.

netbuddy
10-14-2006, 07:44 PM
there's a lot of ways to do it. one would be:
- put all the mp3s in a special directory, that you protect with a .htaccess file (so no one can access anything in that directoy without the proper credentials)
- write a download script that reads the contents of the requested mp3 file (from the protected directory) and outputs it to the user

then, the only thing you need to do with the download script is
1) check whether the user is allowed to download
2) make it safe, so they won't be able to download anything other then those mp3-files.

For those who do not run or have access to an apache server, the .htaccess option would not work.

PHP has the ability to offer up secure downloads, you just need to plan the way in which you allow people to access the site services and how you track the members that purchase from you.

pcthug
10-15-2006, 03:35 AM
Try something like this:

<?php
// Assuming the URL:
// http://www.yourdomain.com/download.php?file=song.mp3&key=h7Nm0PxX5SqG23Laso9visLm37x4Gw8Z

// connect and select db
@mysql_connect('localhost');
@mysql_selct_db('mydb');

// convert query-string variables to inline ones
$file = @mysql_real_escape_string($_GET['file']);
$key = $_GET['key'];

// query the database on the passesed query-string variables
$result = @mysql_query("SELECT file_href, valid_keys FROM files WHERE file = '$file'");

// if no results can be found for the selected query, display error
if(@mysql_num_rows($result) === 0)
{
exit('Invalid file specified');
}

// fetch data as object
$obj = @mysql_fetch_object($result);

// convert and unserialize data into inline variables
$file_href = $obj->file_href;
$valid_keys = unserialize($obj->valid_keys);

// example variable values:
//
// $file = 'song.mp3';
// $key = 'h7Nm0PxX5SqG23676o9visLm37x4Gw8Z';
// $file_href = 'C:/wwwroot/files/song.mp3';
// $valid_keys = array('h7Nm0PxX5SqG23676o9visLm37x4Gw8Z', 'gsnJls02dn8hjKLndo329sjo7sdndfi2');

// if the key is not valid, display error
if(!in_array($key, $valid_keys))
{
exit('You are not authorised to download this file');
}

// if the script has not yet exited, the user has authorisation to download the file

// but before we serve the file we will remove that key from the valid_keys list
// thus that key will not work again

// find and unset current key, then serialize the array for storage inside the database
@unset($valid_keys[array_search($key)]);
$valid_keys = serialize($valid_keys);

// update database, or output error if query fails
if(!@mysql_query("UPDATE files SET valid_keys = '$valid_keys' WHERE file = '$file'"))
{
exit('An unknown error occured, please try refreshing your browser');
}

// and we will force download of the file...
if(ini_get('zlib.output_compression'))
{
ini_set('zlib.output_compression', 'Off');
}

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false); // required for certain browsers
header("Content-Type: audio/mpeg");
header("Content-Disposition: attachment; filename=\"" . basename($file_href) . "\";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($file_href));
readfile($file_href);

echo "Your download of <strong>{$_GET['file']}</strong> should start soon.<br />\n<small>Please note, your key (<em>$key</em>) is now void.</small>\n";

?>It allows the requested file to be downloaded, only if the user has a valid key. When the user has downloaded the file that key automatically becomes void and will not be able to be downloaded again. As for creating the keys, I would just use a simple script like this:
function create_key($valid_key_list)
{
if(!is_array($valid_key_list))
{
trigger_error('create_key(): valid_key_list parameter must be an array', E_USER_ERROR);
return;
}
$token = md5(uniqid(rand(), true));
while(in_array($token, $valid_key_list))
{
$token = md5(uniqid(rand(), true));
}
$valid_key_list[count($valid_key_list)] = $token;
return $valid_key_list;
}

bathurst_guy
10-15-2006, 05:47 AM
What happens if I bought a song, started downloading it and then my Internet connection drops out or something like that, and therefore cancels my download - do I get my money back? Can I download it again?

pcthug
10-15-2006, 06:33 AM
Well as PHP cannot detect whether a file has successfully been downloaded or not, an alternative solution is to set a temporary time limit (say 3 hours) from the first time the file is accessed with the said key.

Or... if you wanted to be even more secure; you could log the IP and User-Agent of the client when they go to download the song. At the bottom of the download page you could have a message that goes along the lines of "... Please do not close this window until your download has completed. If your download fails to download please use this link [current url] ...". That way only a user which has the same IP, User-Agent and HTTP Referer (Should be the same URL) credentials will have access to the file during this temporary time limit.

cabab2020
10-15-2006, 07:38 AM
try this freeware
http://www.webscriptsdirectory.com/PHP/User-Authentication/phpAutoMembersArea-create-own-members-area-L720/