limit downloads per user using session or cookie (postnuke)

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
mazmaz
Forum Newbie
Posts: 1
Joined: Sun Feb 20, 2005 8:37 am

limit downloads per user using session or cookie (postnuke)

Post by mazmaz »

Hi

I am using a postnuke site. I have many pdf files which my members can access. The problem again is people stealing ALL my files in one or two sessions. So I want to limit the number of files each member can download. For example a user can download say 2 files each day.

I am sure it works through sessions somehow but i dont have a clue.
I dont want a massive download program. Just a very simple way of restricting each members downloads at each session.

Any help or advice would be appreciated. I am pretty desperate and I am willing to pay for a bit of code too.

Many thanks

maz
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

If the users are required to login simply create a new table in your database, or even use the existing one, and have a column for "num downloads" .... each time they download increment the value and each time they attempt to download check against this value.

Sessions and cookies arn't the best way to go because a) Once the browser is closed the session is closed b) cookies can be easily deleted.
thegreatone2176
Forum Contributor
Posts: 102
Joined: Sun Jul 11, 2004 1:27 pm

Post by thegreatone2176 »

phneom's way seems the best way to do it but a person can simply make another account and download again, so maybe record the ip of the person downloading and after checking the username status check the ip status
User avatar
smpdawg
Forum Contributor
Posts: 292
Joined: Thu Jan 27, 2005 3:10 pm
Location: Houston, TX
Contact:

Post by smpdawg »

You cannot trust IP address.

If a user is behind a firewall, router, etc. the IP address will be the address of the router not the IP address of the computer. While this might not seem like a problem that does mean that there can be more than one computer behind that IP and no way for you to differentiate between them using only an IP. For example, at home I have 3-4 computers online at any given time and you wouldn't know which one it is because we all have the same IP in the real world.

The second scenario is in companies that use proxy servers, bandwidth management tools, multiple routers, etc. In this case a user may have one IP when they browse a page and then a different IP on the next page load because their internal network is sending them through another router.

The session mechanism in PHP does a good job when it comes to dealing with these two problems and you ought to consider using them to store information about a user BUT you should not trust it for doing what you need to do. You should consider doing the following.

Write a script that accepts the ID of some file to download and a valid user ID. Make sure the user ID is valid. Look in the database to see if that ID had downloaded too many files and optionally deny the download. If it is OK to download, update their counter in the database and let them proceed. The file download would be an action of the script - you would not redirect them or present them with a link. If you do it this way, you can store the files off the web root so they cannot be accessed directly and can only be downloaded via the script. Remember - this is ONE script that does everything and try your best to set the path of the files somewhere that is not accessible via the internet but is available to the web server.

Using this scenario you can use cookies and/or session data to only validate the user because it is merely an aid to login and not a way of controlling downloads. This makes the script tolerant of the fact that someone may try to cheat and it would nip it in the bud by denying the download. The only gotcha is that if someone aborts the download, it still counts as a download because the transfer was initiated but that should not happen very often. In this case you could allow them a grace download if they attempt to download a file that they had tried earlier in the day.

BTW - This is not a theory, I have already done it in PHP.
User avatar
smpdawg
Forum Contributor
Posts: 292
Joined: Thu Jan 27, 2005 3:10 pm
Location: Houston, TX
Contact:

Post by smpdawg »

BTW - Here is some pseudo-code and a fragment that does the actual download. You could put all this code in some file called download.php or something like that. I would highly recommend that you use some sort of file ID rather than a path because that could open the door for someone to download sensitive files from you server if they guess where the file is like /etc/passwd...

Code: Select all

// Step 1. Validate user  
// Step 2. See if the download limit was reached.
// Step 3. Make sure the file exists.
// Step 4. Update the download count table to show that a download was begun for that user.
// Step 5. Remember to NEVER USE register_globals.
  
  if ($SomeVariableThatSaysItIsOKToDownload == true) {
    // These are the headers to send a file to the browser.  
    // $FileName is the desired file name - not necessarily the path to an existing file but instead the name of the file as you would like it to be saved.  
    // Please not the IE doesn't necessarily honor this value.
    header("Content-disposition: attachment;  filename=" . $FileName . ";" ); 
    header("Content-Type: application/octet-stream"); 
    header("Content-Type:  application/force-download"); 
    header("Content-Type: application/download"); 
    header("Pragma: no-cache");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0, public"); 
    header("Expires: 0"); 

    // This does a cheap file open of the file specified by $FullFilePath to the standard output.  This does the actual download.
    readfile($FullFilePath); 
  } else {    
    // Obviously you would give an explanation to the user here about why they cannot download the file.
    echo "If you are seeing this message, the you couldn't download this file for some reason.";
  }
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

http://timvw.madoka.be/programming/php/download.txt

my way of a download script :) it's like the one posted here, only it also tries to identify the mimetype...
User avatar
smpdawg
Forum Contributor
Posts: 292
Joined: Thu Jan 27, 2005 3:10 pm
Location: Houston, TX
Contact:

Post by smpdawg »

Where was your code when I needed it? LOL

Do people throw money? If so, I am going to put my PayPal info up there. :D
Post Reply