Apache mod_rewrite Based on Logged in User
I’ve been working on a project recently where I want to redirect users logging into Apache to that user’s personal directory. There is a lot of incorrect information out there.
Most sites recommend something close to the following: (NOTE: This is wrong)
RewriteEngine On
RewriteCond %{REMOTE_USER} uid=([^,]+),
RewriteRule ^/users/$ /users/%1
There’s a few problems with this.
- The
RewriteCondmatch pattern is completely wrong.%{REMOTE_USER}won’t containuid=and should not be part of the match. - In the RewriteRule
%1has no meaning so if this matched it would redirect get sent into an infinite loop, since/users/redirects to/users/. - Because of the way mod_rewrite works
%{REMOTE_USER}isn’t necessarily populated and may be empty. If this is the case, the entire block will be skipped.
As I’ve said before (mostly to remind myself) reading the documentation is essential.
For instance, to rewrite according to the
REMOTE_USERvariable from within the per-server context (httpd.conf file) you must use%{LA-U:REMOTE_USER}- this variable is set by the authorization phases, which come after the URL translation phase (during which mod_rewrite operates).On the other hand, because mod_rewrite implements its per-directory context (
.htaccessfile) via the Fixup phase of the API and because the authorization phases come before this phase, you just can use%{REMOTE_USER}in that context.
There are basically two options here. If you’re adding the RewriteRule into
your main Apache config file (httpd.conf), mod_rewrite runs before
authentication. In this cause you need to use a look ahead assertion.
If you’re using a .htaccess file in a directory then mod_rewrite runs
after authentication.
So if you’re adding the rule to your Apache server config (httpd.conf) the final rule looks like this:
RewriteEngine On
RewriteCond %{LA-U:REMOTE_USER} ^[a-z].*
RewriteRule ^\/(.*)$ /%{LA-U:REMOTE_USER}/$1
And for .htaccess:
RewriteEngine On
RewriteCond %{REMOTE_USER} ^[a-z].*
RewriteRule ^\/(.*)$ /%{REMOTE_USER}/$1