Please include the list when replying. On Wed, Jul 6, 2011 at 10:20 PM, Kirk Bailey <kbailey@xxxxxxxxxxxxxxxx>wrote: > Um, assuming dishonest intent on the customers part, why would the token > NOT be shared? > I meant shared within your system between customers. Whether you lock the URL or not, if customers want to share the asset(s) they're downloading, they will. Nothing you can really do about that. > On 7/6/2011 4:34 PM, Stuart Dallas wrote:If you read back you'll note I > said "generate a unique token linked to their account." At no point did I > say the tokens would be shared between customers. > Perchance, you have wroking code addressing this sort of issue? Could you > post it here for all to examine please? Not without breaching various copyright laws, but I can go through the general process :). The following assumes you don't have a user DB, or don't want the tokens to be connected to the users. You have a data source (DB, whatever) that can store unique tokens with other data. For the sake of example let's go with a standard DB. You create a table that contains fields... - id (unsigned int auto_increment) - token (char(40) with a unique key) - expires_at (unsigned int) - product_id (unsigned int) Customer buys something. Once payment is confirmed the site does this... 1) Insert a row into the table... - expires_at = time() + 86400 for 24 hours, time() + 900 for 15 minutes, etc - product_id = the ID of the product they purchased (modify this to include what you need to deliver the item[s] they've purchased) 2) Retrieve the last inserted ID. 3) Hash (sha1) or encrypt (mcrypt_encrypt) the ID with a secret salt [i.e. $token = sha1('this is the '.$id.' secret salt'); or similar]. If you use mcrypt you may need to modify the result to be usable in a URL - read the manual. 4) Update the row with that token. Catch duplicate key errors (unlikely but possible), go back to 3 and try again with a different salt (adding a random character will do). How you generate the token is essentially irrelevant, so long as you can't deduce another token from the one you have. I've found the above to be sufficient, and it very very rarely generates a duplicate. When a download URL is hit it runs a script that does the following... 1) Make sure a token has been provided in the URL. 2) Select the row corresponding to that token from the table. 3) If no row was found display "access denied" or "download expired", along with your support email address. 4) If ($row['expires_at'] < time()), delete the row (optional) and display "access denied" or "download expired", along with your support email address. 5) If not, use the product_id (or whatever) to deliver the download by writing out the correct headers and then use readfile() to send it. Note that if the downloads are large you may want to do this a different way so you can catch and deal with client disconnects. That's basically it. To keep the table clean you can have a cron job that does a simple "delete from table where expires_at < unix_timestamp();" query every 24 hours, or depending on how long the query takes you could simplify it by running that same query during a suitable percentage of the download URL hits. You may also see benefits by connecting the table above to the user and order tables (or whatever equivalents your system may have). Hope that makes it a bit clearer. -Stuart -- Stuart Dallas 3ft9 Ltd http://3ft9.com/