Click to See Complete Forum and Search --> : [RESOLVED] htaccess and forums
Slyke
Apr 15th, 2009, 11:28 AM
Hey guys,
I'm just wondering how it would be possible to restrict a directory on a server depending if a user is logged into a forum or not.
Basically the directory structure is this:
public_html/forum
public_html/ftp_area
The htaccess file will have to go into the public_html folder. Making sure the forum directory stays unlocked (So users can actually login, lol).
I want the ftp_area folder restricted if a user isn't logged into the forum software (phpBB if anyone's interested). I'm thinking that you'd have to check whether they are logged in by checking cookies. I could modify the boards to set another cookie that the script could check, or design something that checks the phpBB database. The only thing is that this script would have to run if they tried to access any file or sub-directory under and including "ftp_area".
I know enough of PHP to do this, but am a little lost when it comes to htaccess files.
Is this possible to do?
kows
Apr 15th, 2009, 10:11 PM
you couldn't use htaccess to do any of this. it can't interact with cookies like you're wanting to do.
you could do this with PHP; you'd just need to have every page in the "ftp_area" folder check if the user is logged in -- and if not, you would redirect them to the login. if you're thinking this won't work because your "ftp_area" will be full of files or something that you only want registered users to have access to, then you can easily work around this as well. when linking to files, you can simply use a script to request files for the user via headers and then store the files in a random folder. you could even set up a table in your database and rename files based on an ID or a hash of the filename/file contents.
hope that makes sense! don't have any code to post as an example cause I'm in a hurry, you should be able to find examples by looking up the header() function though!
kows
Apr 15th, 2009, 11:02 PM
here is an example of how to send a file via headers (from php.net):
<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');
// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');
// The PDF source is in original.pdf
readfile('original.pdf');
?>
you can find more information here (http://ca2.php.net/manual/en/function.header.php), especially from the comments.
if you have any other questions about how you might accomplish what you're doing (especially if you're confused by my rambling above), feel free to ask questions!
Slyke
Apr 16th, 2009, 06:42 AM
Hey kows, thanks for the input :).
Would it be possible to put a htaccess file in the main directory, that tells the apache to run a php file when ever a file, or folder is requested?
I could then do the deciscion making (Redirect them to an error page, or allow the file to go through from the script). If not then I'll just have to do it the hard way, lol!
kows
Apr 16th, 2009, 03:06 PM
you could use mod_rewrite to send a user in the ftp_area directory to a PHP script, which could then check if the user is logged in. but then, you really couldn't just redirect them after this because either A: mod_rewrite would pick it up again and it would just be an infinite loop; or B: an unlogged in user would be able to see the page you're redirected to, if given the URL by a real logged in user. so, if you did do this, you would need to do all page handling in the PHP script you're sending the user to, most likely by parsing the URI and figuring out what they want. if you're serving up pages, you could simply check if the user is logged in, and then if not you could include the page they're looking for. or, if you're serving up files, you could check if the user is logged in, and then send them a file with the header() method described above. you will still need to have all of these files "hidden" in some way, because a regular user could still just waltz up and look at them if he knew the "real" filenames. so, if you would do it this way, it would still be the same method as above (basically), but it would have prettier URLs.
so without any more rambling, here is an example of an htaccess file using mod_rewrite:
in the "ftp_area" directory, .htaccess:
#turn on rewrite engine
RewriteEngine On
#redirect every request in this directory to a script in another directory
RewriteRule (.*) /safe_dir/?$1 [L]
in "safe_dir", index.php:
<?php
//put your login logic here.
if($login == false){
header("Location: /forums/login.php");
}else{
echo "hello, $username! you requested: " . $_SERVER['QUERY_STRING'];
}
?>
so, if a user goes to /ftp_area/some/directory/file.rar, then the browser's URL will be the same, but the user will be redirected to /safe_dir/index.php?some/directory/file.rar, which would let you then include/send the file or do whatever you want. this means that all of your actual files should be stored in "safe_dir" but every URL you have should be pointing to the "ftp_area" directory. this "ftp_area" directory only needs to have the htaccess file in it.
hope that all made sense.
Slyke
Apr 17th, 2009, 08:20 AM
kows, that made perfect sense.
I'm just basically sending that file to the user, but the only thing is that is will be going through that script (By modifying the header as you said). If they arn't logged in then they get redirected to the login page.
That's not what I had in mind, but hey it works and it's still just as awesome :). By designing it this way it also opens the door for certain users only having access to certain areas too.
I'm going to give this a shot and let you know how it went :).
Slyke
Apr 22nd, 2009, 12:32 AM
I had to tweak it a little bit, but I got it working :D.
Would it be possible to have it list all the files in a directory when they don't navigate to a file? I mean, even if there's an index file in a directory?
So basically, if they are not logged in, redirect to login page.
If they are logged in, and request a file, then let them download the file. If they don't request a file (Just a directory), then list the contents of the directory).
I have added the following code to the script as well:
if (is_file('../ftp_area/' . $_SERVER['QUERY_STRING']))
{
readfile('../ftp_area/' . $_SERVER['QUERY_STRING']);
}
else
{
header("Location: http://www.thedomain.info/safe_dir/404.php?f=" . $_SERVER['QUERY_STRING']);
}
kows
Apr 22nd, 2009, 04:21 AM
you're already using is_file(), you should also be able to just use is_dir().
<?php
//REAL path for verification
$rpath = "../safe_dir/{$_SERVER['QUERY_STRING']}";
//fake path for displaying
$fpath = $_SERVER['QUERY_STRING'];
if(is_dir($rpath)){
//add slash for URLs -- only directories though
if(substr($fpath, -1) != "/")
$fpath .= "/";
//print dir
?><h1><?php echo $fpath; ?></h1>
<blockquote><?php
$dh = opendir($rpath);
$i = 0;
while (($file = readdir($dh)) !== false) {
if($file != "." && $file != "..") {
$i++;
//link to the "masked" URL!
?>
<?php echo $i; ?>. <a href="/ftp_area/<?php echo $fpath . $file; ?>"><?php echo $file; ?></a><br />
<?php
}
}
closedir($dh);
?></blockquote><?php
}elseif(is_file($rpath)){
//readfile
}else{
//redirect
}
?>
edit: added some path stuff.
and as an aside, the directory listing WILL list all directories too. to filter out either files or directories you can use is_file() and is_dir() calls on $rpath.$file; or simply use filetype() to tell the user that they are a directory or a file.
Slyke
Apr 23rd, 2009, 12:47 AM
So basically I have to create a script that lists all the files and directories (After checking if it's a directory), and can't use the one that comes with Apache?
kows
Apr 23rd, 2009, 12:59 AM
well, no, because you're redirecting the user to a script; the directory you're masking doesn't technically exist, so apache wouldn't have any clue what to do. you could make something that looked and acted just like apache's directory listing would, though.
Slyke
Apr 23rd, 2009, 06:29 AM
Ok, Thanks dude :). I'll post here if I have any troubles creating it!
Slyke
Apr 25th, 2009, 05:49 AM
Thanks, it works a treat :D.
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.