This is a discussion on Can I use $_SESSION to limit access to directories? within the PHP Language forums, part of the PHP Programming Forums category; I have a login script that creates a SESSION for authenticated users. But authenticated users still need access to particular ...
|
|||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
|
|||
|
I have a login script that creates a SESSION for authenticated users. But
authenticated users still need access to particular directories (which contain files for download). My hosting provider lets me protect directories with htaccess, but this means an already authenticated user must enter credentials a second time in the pop up dialog that appears in the browser window when attempting to download something from an htaccess-protected directory. AFAIK, there is no way to pass credentials to htaccess. How do I protect an authenticated user's files and/or directories? Is there an alternative to htaccess? Thanks in advance. |
|
|||
|
*** deko escribió/wrote (Sat, 12 Mar 2005 19:59:23 GMT):
> I have a login script that creates a SESSION for authenticated users. You already have 95% of work done. Now... Can you use these credentials to protect directories? No, you cannot, as far as I know. PHP will never handle the directory listings created by Apache, JPEG files, PDF files, etc. Can you use these credentials to protect PHP files? Sure. This simpliest way: <? if( !isset($_SESSION['authenticated_user_id']) || $_SESSION['authenticated_user_id']!=666 ){ die('Unauthorized'); } ?> > How do I protect an authenticated user's files and/or directories? The typical option is moving them outside the public web directory, where they cannot be served by Apache. Then do not link the files, link a download script written in PHP. -- -+ Álvaro G. Vicario - Burgos, Spain +- http://www.demogracia.com (la web de humor barnizada para la intemperie) ++ Manda tus dudas al grupo, no a mi buzón -+ Send your questions to the group, not to my mailbox -- |
|
|||
|
> The typical option is moving them outside the public web directory, where
> they cannot be served by Apache. Then do not link the files, link a > download script written in PHP. So that's how it's done. Thanks for the tip. Here's what I've tried: The link in the secure (SSL-encrypted) page looks like this: <a href='../../dlcounter.php?file=somefile.zip|username'>somefile .zip</a> [dlcounter.php] $dlfile = trim($_GET[file]); $dlfile = explode("|", $dlfile); switch ($dlfile[1]) { case "thisuser": $dlpath = '/home/myispacct/thisuser/'.$dlfile[0]; break; case "thatuser": $dlpath = '/home/myispacct/thatuser/'.$dlfile[0]; break; case "otheruser": $dlpath = '/home/myispacct/otheruser/'.$dlfile[0]; break; default: $dlpath = 'http://www.mysite.com/PublicDownload/'.$dlfile[0]; } [code to record download user and time goes here] echo $dlpath; So far so good. But how do I start the download? I hope this is not too silly a question... |
|
|||
|
*** deko escribió/wrote (Sun, 13 Mar 2005 21:17:25 GMT):
> <a href='../../dlcounter.php?file=somefile.zip|username'>somefile .zip</a> Just be aware that it's awfully easy to rewrite the URL. Get the username when you validate the user and keep it in a variable session. > $dlpath = 'http://www.mysite.com/PublicDownload/'.$dlfile[0]; [...] > So far so good. But how do I start the download? readfile() will do the trick. You can additionally generate the appropriate content type header with header('Content-Type: ......'). > I hope this is not too silly a question... Of course not :) -- -+ Álvaro G. Vicario - Burgos, Spain +- http://www.demogracia.com (la web de humor barnizada para la intemperie) ++ Manda tus dudas al grupo, no a mi buzón -+ Send your questions to the group, not to my mailbox -- |
|
|||
|
> > <a
href='../../dlcounter.php?file=somefile.zip|username'>somefile .zip</a> > > Just be aware that it's awfully easy to rewrite the URL. Get the username > when you validate the user and keep it in a variable session. So, would you suggest something like this: <a href='../../dlcounter.php?file=$_SESSION['uid']>somefile.zip</a> The problem with using the session variable is that the session is lost when going from the SSL-encrypted private user page to the dlcounter.php script. Is it possible to reference the script like this: https://www.mysite.com/dlcounter.php But then the script would have to be in a publicly-accessible area. Is that a problem? > readfile() will do the trick. You can additionally generate the appropriate > content type header with header('Content-Type: ......'). That's the ticket! Thanks! I got it working with this (stripped down version of dlcounter.php): <?php header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=test.txt" ); readfile("/home/myispacct/secure/test.txt"); ?> One more question: Is is better to use: header("Content-Type: application/force-download") or header("Content-Type: application/octet-stream"); ? |
|
|||
|
> > <a
href='../../dlcounter.php?file=somefile.zip|username'>somefile .zip</a> > > Just be aware that it's awfully easy to rewrite the URL. Get the username > when you validate the user and keep it in a variable session. I also tried this: <a href='https://hostname.myisp.com/myacct/dlcounter.php'>somefile.zip</a> The SSL state appears to be preserved as it goes to dlcounter.php, but I can't get the SESSION variable value. If I put this in dlcounter.php: echo $_SESSION['uid']; exit; Nothing is echoed on the screen. I set $SESSION['uid'] on the login page: $_SESSION['uid'] = $user; $url="https://hostname.myisp.com/myacct/someuser/privatepage.php"; header('Location: '.$url); //redirect to privatepage.php echo $_SESSION['uid'] will return the correct value on privatepage.php - but not on dlcounter.php. Is there some reason why the variable is lost when clicking on the link in privatepage.php? Do I need to set another Session variable for the purpose of secure downloading? |
|
|||
|
> echo $_SESSION['uid'] will return the correct value on privatepage.php -
but > not on dlcounter.php. Is there some reason why the variable is lost when > clicking on the link in privatepage.php? Do I need to set another Session > variable for the purpose of secure downloading? oops... session_start(); echo "SESSION[uid] = ".$_SESSION['uid']; exit; now it works :) |
|
|||
|
making progress, but...
---link in privatepage.php--- <a href='https://hostname.myisp.com/myacct/dlcounter.php?file=test.zip'>test.zi p</a> ---code in dlcounter--- <?php session_start(); $dlfile = trim($_GET[file]); switch ($_SESSION['uid']) { case "someuser": $dlpath = 'home/myacct/someuser/'.$dlfile; break; default: $dlpath = 'http://www.mysite.com/PublicDownload/'.$dlfile; } header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=".$dlfile); readfile($dlpath); The download dialog appears, but the download fails becuase path to the file is getting screwed up. In the File Download dialog, the File Name appears not at "test.txt", but as a url to dlcounter.php. Perhaps this is because it's looking for a SSL-encrypted path? How to get it to go to the correct path? Is this possible when connecting to an SSL-encrypted dlcounter.php? Thanks again for the help. |
|
|||
|
*** deko escribió/wrote (Sun, 13 Mar 2005 23:30:47 GMT):
>> Just be aware that it's awfully easy to rewrite the URL. Get the username >> when you validate the user and keep it in a variable session. > > So, would you suggest something like this: > > <a href='../../dlcounter.php?file=$_SESSION['uid']>somefile.zip</a> I would suggest NOT doing so. What prevents me from typing any username in my browser's location bar? > The problem with using the session variable is that the session is lost when > going from the SSL-encrypted private user page to the dlcounter.php script. Then transmit the session ID in the URL when moving to SSL zone. Check this: http://es.php.net/manual/en/function.session-id.php Or you can also use SSL since login. -- -+ Álvaro G. Vicario - Burgos, Spain +- http://www.demogracia.com (la web de humor barnizada para la intemperie) ++ Manda tus dudas al grupo, no a mi buzón -+ Send your questions to the group, not to my mailbox -- |
|
|||
|
*** deko escribió/wrote (Mon, 14 Mar 2005 00:57:21 GMT):
> $dlpath = 'home/myacct/someuser/'.$dlfile; > break; > default: > $dlpath = 'http://www.mysite.com/PublicDownload/'.$dlfile; > } > header("Content-Type: application/octet-stream"); > header("Content-Disposition: attachment; filename=".$dlfile); > readfile($dlpath); > > The download dialog appears, but the download fails becuase path to the file > is getting screwed up. In the File Download dialog, the File Name appears > not at "test.txt", but as a url to dlcounter.php. Perhaps this is because > it's looking for a SSL-encrypted path? How to get it to go to the correct > path? Is this possible when connecting to an SSL-encrypted dlcounter.php? I'll try to explain myself better. The problem is that you can't password protect directories. So we've moved files outside the web server root and we are using a script to download them. If your script loads files from within the web server root, we're doing nothing! Your users can override the script and point their browsers to the actual URL. You want your script to read from the *file system*, from a directory that's hidden to browsers. -- -+ Álvaro G. Vicario - Burgos, Spain +- http://www.demogracia.com (la web de humor barnizada para la intemperie) ++ Manda tus dudas al grupo, no a mi buzón -+ Send your questions to the group, not to my mailbox -- |