Forum Moderators: phranque

Message Too Old, No Replies

Mod_Rewrite : Redirect page based on authentication

Stuck for a month now ...any help will receive my highest appreciation

         

weiheon

6:12 am on Jun 9, 2005 (gmt 0)

10+ Year Member



Hi Webmaster World and fellow members,

Im stuck in a moment and I can't get out of it. Here's the scenario:

I have multiple directories for different users. In each directory contains html pages that can only be viewed by certain users. I control these directories using .htaccess and AuthConfig. Let say I have user tom, dick and harry and they login at www.mainsite.com. Based on the authentication ID, the users will be redirected to their directory page. So my filesystem will be organised like below :

/home/mainsite/index.html
/home/mainsite/tom/page.html
/home/mainsite/dick/page.html
/home/mainsite/harry/page.html

in my httpd.conf : -

<VirtualHost #*$!.#*$!.#*$!.xxx>
DocumentRoot /home/mainsite/
ServerAdmin admin@mainsite.com
ServerName www.mainsite.com

TransferLog /somewhere/some-log
ErrorLog /somewhere/some-error_log
DirectoryIndex index.html

<Directory "/home/mainsite/tom">
Options +ExecCGI Includes FollowSymLinks
AllowOverride AuthConfig FileInfo
Order allow,deny
Allow from all
</Directory>

<Directory "/home/mainsite/dick">
Options +ExecCGI Includes FollowSymLinks
AllowOverride AuthConfig FileInfo
Order allow,deny
Allow from all
</Directory>

<Directory "/home/mainsite/harry">
Options +ExecCGI Includes FollowSymLinks
AllowOverride AuthConfig FileInfo
Order allow,deny
Allow from all
</Directory>

</VirtualHost>

in /home/mainsite/.htaccess

AuthType Basic
AuthName "Restricted Page"
AuthUserFile /home/httpd/passwd/user-passwd
require valid-user

in /home/mainsite/tom/.htaccess

AuthType Basic
AuthName "Restricted Page"
AuthUserFile /home/httpd/passwd/user-passwd
require user tom
RewriteEngine on
RewriteCond %{REMOTE_USER} =^tom$
RewriteRule ^/(.*) [mainsite.com...] [R,L]

I have not edit anything in the .htaccess file for the rest of the user's directory since I couldn't get it to work on one of the directory(tom). The authentication works fine without any problem. That is only certain users are able to access their respective page. But I failed to get mod_rewrite to redirect the page as the /mainsite/index.html page was loaded after the authentication was done at the /mainsite/.htaccess file. Please correct my syntax if you could find the mistakes. PLEASE HELP! T_T

Regards,
Yap Wei Heon
Systems Administrator

weiheon

8:50 am on Jun 9, 2005 (gmt 0)

10+ Year Member



Hi again,

There is another doubt : -

in /home/mainsite/tom/.htaccess

AuthType Basic
AuthName "Restricted Page"
AuthUserFile /home/httpd/passwd/user-passwd
require user tom
RewriteEngine on
RewriteCond %{REMOTE_USER} =^tom$
RewriteRule ^/(.*) [mainsite.com...] [R,L]

Did I insert the mod_rewrite codes into the wrong .htaccess file? which .htaccess file should I edit for my problem?

1. /home/mainsite/.htaccess?
or
2. /home/mainsite/tom/.htaccess?

Regards,
Yap Wei Heon

jdMorgan

2:58 pm on Jun 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



weiheon,

Welcome to WebmasterWorld!

In /home/mainsite/.htaccess


RewriteCond %{REMOTE_USER} ^tom$ [NC]
RewriteCond $1 !^tom/
RewriteRule (.*) /tom/page.html/$1 [L]

Comments:

1) You can also do this authentication work in httpd.conf, rather than using .htaccess, but I tried to answer your question as posted. If you do it in httpd.conf, then you wont need the additional RewriteCond to prevent looping.

2) Be aware of the slight differences in RewriteRule local URL-path patterns between httpd.conf and .htaccess context. In .htaccess, the path to the current directory is stripped from the URL-path seen by RewriteRule. The simple case is that RewriteRule will match "^/dir/subdir" in httpd.conf, but a RewriteRule in an .htaccess file located in the Web root (home) directory sees "^dir/subdir" (no slash). Located in "/dir", it sees only "^subdir".

Jim
[edit] Corrected as noted below in msg #9 [/edit]

[edited by: jdMorgan at 6:07 am (utc) on June 13, 2005]

weiheon

1:26 am on Jun 10, 2005 (gmt 0)

10+ Year Member



Hi Jim,

Thank you so much for your reply. You are the only person that replied to my problem(after days of surfing and posting various forums) and on the edge of giving up, you shed some light to me.

However, after making the changes you suggested, my .htaccess file looks like this : -

in /home/mainsite/.htaccess

AuthType Basic
AuthName "Restricted Page"
AuthUserFile /home/httpd/passwd/user-passwd
require valid-user
RewriteEngine on
RewriteCond %{REMOTE_USER} ^tom$ [NC]
RewriteCond $1!^/tom/
RewriteRule (.*) /tom/page.html/$1 [L]

When I login at www.mainsite.com as user tom, I receive a page error 403, Access Forbidden!.

'Access forbidden!
You don't have permission to access the requested directory. There is either no index document or the directory is read-protected.

If you think this is a server error, please contact the webmaster

Error 403'

I can feel that it's trying to redirect the page by the loading time it takes before it displays the error page. I thought it was a file/dir permission issue, so I did a 'chown root:webmaster' for /tom/ directory as well as /tom/page.html file. But still no luck. Please forgive me if this simple for you, I tried to understand mod_rewrite but it's just not as easy as I thought. Any clue?

Thanks and Regards,
Yap Wei Heon

weiheon

1:53 am on Jun 10, 2005 (gmt 0)

10+ Year Member



Sorry for the typo, there should be a space after $1 at

'RewriteCond $1!^/tom/' ,please help! T_T

jdMorgan

1:59 am on Jun 10, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yes, well I'm not sure I understand exactly why you wrote your original code the way you did. All I did was to correct the syntax slightly. Be aware that this rule:
 RewriteRule (.*) /tom/page.html/$1 [L] 

will rewrite a request from user "tom" for www.example.com/foo to /tom/page.html/foo
and it will rewrite Tom's request for www.example.com/bar.php to /tom/page.html/bar.php

So I'm not really sure why you have the "/page.html" in there, but I assumed you wanted it.

Whenever you get an error, open your server error log and look for the error (you can usually find it easily by the timestamp). It will often show you very useful details about the error.

Jim

weiheon

3:26 am on Jun 10, 2005 (gmt 0)

10+ Year Member



Hi Jim,

I would like to apologize for the confusion. My main intention was to redirect users to their main page in their allocated directories. In my case when user tom log's in at www.mainsite.com he will be redirected /home/mainsite/tom/page.html.

I am not running any scripts(cgi,php). Anyway, I've successfully redirected the page. WALLA! I would have kissed you if you were sitting next to me now =). I have did some modifications again after what you mentioned in your previous post about the request will rewrite www.example.com/foo to /tom/page.html/foo.

RewriteEngine on
RewriteCond %{REMOTE_USER} ^tom$ [NC]
RewriteRule (.*) /home/mainsite/tom/page.html [L]

But now I've hit another problem where all of the image files (png) associated with the page cannot be loaded. After going thru the logs, I think i know what was wrong : -

some.one.com - tom [10/Jun/2005:11:04:07 +0800] "GET /graph_1-day.png HTTP/1.1" 200 8706
some.one.com - tom [10/Jun/2005:11:04:07 +0800] "GET /graph_1-week.png HTTP/1.1" 200 8706

The path to the png files should be in /tom/graph_1-day.png and /tom/graph_1-week.png but now its looking for the files at the wrong place. But how do I fix this?

Yap Wei Heon

jdMorgan

2:58 pm on Jun 10, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Your new version redirects *all* requests to <user>/page.html, no matter what is requested.

Be aware that there's no magic here -- mod_rewrite takes only the information you provide and does the rewrite. It has no "awareness" of any "current state" information about the user's session -- as a matter of fact, Apache itself is not state-aware. There is only the current HTTP request in Apache's view.

If you simply want to redirect any request from <user> to <users>'s subdirectory, then you need the opposite modification:


RewriteEngine on
RewriteCond %{REMOTE_USER} ^tom$ [NC]
RewriteRule (.*) /home/mainsite/tom/$1 [L]

Any required special handling of the login page would then be an exception to this rule.

Now I need to warn you about something else, and that is that such rules in .htaccess can loop. This is because after any rewrite is done, httpd.conf and ant .htaccess files in the newly-rewritten path must be re-executed, in order to test for rewrites and/or access restrictions on the newly-rewritten URL-path.

So, it's likely your code will rewrite to /home/mainsite/tom/<file>, and then rewrite to /home/mainsite/tom/tom/<file> and then to /home/mainsite/tom/tom/tom/<file> etc.

In order to stop this, you must provide the information needed to determine if the rewrite has already taken place. In this case, you can use the fact that after the rewrite, "Tom" will appear in the new URL-path:


RewriteEngine on
RewriteCond $1 !^tom/
RewriteCond %{REMOTE_USER} ^tom$
RewriteRule (.*) /home/mainsite/tom/$1 [L]

But the code does not scale well -- you have to add a new ruleset for each new user. So perhaps a different method that does not depend on the user-name would be better. The simplest way to do this is to start each user-subdirectory with a unique string, and look for that string to determine whether the rewrite has already been done:


RewriteEngine on
RewriteCond $1 !^user_
RewriteCond %{REMOTE_USER} ^([a-z0-9_]+)$
RewriteRule (.*) /home/mainsite/user_%1/$1 [L]

This rewrites requests from tom for <file> to /home/mainsite/user_tom/<file>, and does the same for any other user. Note that the pattern in the 2nd rule places restrictions on usernames; They can be made up of lowercase letters, numbers, or the underscore character only. This is to prevent creating invalid filepaths.

Jim

weiheon

6:00 am on Jun 13, 2005 (gmt 0)

10+ Year Member



Hi Jim,

Amazing! Your suggestions has helped me to solve my month long problem. I took the last few days figuring out why it wasn't working using your codes and I had just found out there was an additional "/" in one of my rewrite condition. (RewriteCond $1!^/tom/). I guessed I was confused by your first post to this thread where stated in your code the "/" was present. Here we go : -

RewriteEngine on
RewriteCond $1!^tom/
RewriteCond %{REMOTE_USER} ^tom$ [NC]
RewriteRule (.*) /home/mainsite/tom/$1 [L]
RewriteCond $1!^dick/
RewriteCond %{REMOTE_USER} ^dick$ [NC]
RewriteRule (.*) /home/mainsite/dick/$1 [L]
RewriteCond $1!^harry/
RewriteCond %{REMOTE_USER} ^harry$ [NC]
RewriteRule (.*) /home/mainsite/harry/$1 [L]

I have to create the redundant rewrite codes for each user as their directives are not the same/equal to their login. But your example below will prove handy for many people with similar problems: -

RewriteEngine on
RewriteCond $1!^user_
RewriteCond %{REMOTE_USER} ^([a-z0-9_]+)$
RewriteRule (.*) /home/mainsite/user_%1/$1 [L]

This is a really great community. Bazillion thanks to Jim and Webmaster World. You guys make mod_rewrite look easy.

Yap Wei Heon

jdMorgan

6:09 am on Jun 13, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Glad you got it working!

I corrected my first post above so that others will benefit from your work. Sorry for the error...

Jim