Apache .htaccess - applying basic authentication conditionally based on environment or hostname

Devin Emke picture Devin Emke · Jun 17, 2012 · Viewed 13.2k times · Source

My dev setup: Mac OSX 10.7.4 / Apache 2.2.21 / PHP 5.3.10

I wish to add conditional logic to my .htaccess files depending on dev vs live environment. for example i want to have authentication on the live server but not on the dev server. i have in my httpd.conf

SetEnv DEV 1

I have confirmed that this var is set by checking the output from phpinfo(). then in my .htaccess file

<IfDefine !DEV>
  AuthType Basic
  AuthName "password protected"
  AuthUserFile /path/to/.htpasswd
  Require valid-user
</IfDefine>

...but I am still prompted for password on my local dev. it appears that the DEV variable is not available to .htaccess. I do have AllowOverride All set in my httpd.conf for my doc root. Any ideas?

Answer

Nerivon picture Nerivon · Sep 7, 2012

I am fresh off of about 4 hours into this problem, and I believe I have the final answer and can summarize for everyone how to solve this particularly painfull problem.

I am using Windows 7 Home Premium with Apache 2.2x and Php 5.3 as my dev machine. I too want to have a DEV environment variable, which I can use in my .htaccess files to turn off Rewriting and other directives which are not valid on my develpment environment but are critical to my production environment.

My .htaccess file looks like this;

<IfDefine !__DEV__>
    AddType application/x-httpd-php53 .php
</IfDefine>

HostGator informed me that in order to have php 5.3 I needed to modify my htaccess file like this to enable it or I'd only have php 5.2. But I already have it on my dev machine so, this directive was causing my customer website to crash when I viewed it locally. Everything I'm about to explain has allowed me to keep ONE .htaccess file in my Git Repository, which works in both locations.

First, let me clear/sum up all the things I learned while scouring the internet for the way to use IfDefine and SetEnv to solve this issue;

  1. The IfDefine directive in Apache, Only , ONLY and when I say only i mean ONLY, responds to parameters passed at the command line. Let me emphasize that a little. ONLY COMMAND LINE!
  2. SetEnv and SetEnvIf, are two entirely different things. One (SetEnv) is for use in the conf files, setting environment variables (specific to apache) which are set at SERVER START TIME. SetEnfIf is used at REQUEST TIME and is only used to determine what to set based on REQUEST variables.
  3. The IfDefine directive does not read variables set by SetEnv or SetEnvIf. Period. There's no argument, there's no question, there's no "but i thought..." NO. It doesn't, so get over it.

The short answer is NO, you can't just use "SetEnv DEV 1" in httpd.conf and then use IfDefine to detect it in your .htaccess file, which would seem intuitive and reasonable based on the syntax and nature of programming logic any of us are used to. Recall that we are not in fact programming anything, that these are config files and of course they don't conform to this expectation simply because it seems like they should.

The Answer

So this means that I have to figure out how to add a startup parameter to Apache, well for the Linux Guys, that answer is readily available, you just have to add the right stuff to the envvars file, but what about us poor windows junkies?

Well for windows users it gets more fun for the following reasons:

  1. Windows does not allow you to permanently add startup parameters in the services configuration for Apache2.2 (it doesn't work, don't try it, I've done it a million times, trust me). This is true, if you go in there and try to put in your own parameters, it will only work one time and then the parameter field is empty the next time you open the dialog. I don't know why this is the case, but it seems that those parameters are intended for testing, not a permanent modification.
  2. When Apache is installed it creates "Start", "Stop" and "Restart" shortcuts in the start menu, as well as installs the Apache Services Monitor. BUT the shortcuts in the start menu use different startup parameters than those used by apache services monitor. So if you start/stop apache using a combination of these methods you will get different results depending on what method you used. However, you can put the -D "__DEV__" in the start menu shortcut and it will work!

Steps to Solve It

To permanently and universally setup a __DEV__ environment variable which you can reference using IfDefine in .htaccess files, on a Windows Development environment which will work whether you start Apache using a service or the shortcuts in the start menu or using NET START/STOP on the command line, do the following:

  1. Open the properties for the start menu shortcut and extract the command you find for starting Apache there. Mine was; "C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin\httpd.exe" -w -n "Apache2.2" -k start

  2. Modify it to include the new -D __DEV__ variable, which MUST go at the start immediately following httpd.exe; "C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin\httpd.exe" -D "__DEV__" -w -n "Apache2.2" -k start

  3. Your start menu shortcut will now start apache with your dev variable in place.

  4. Go to a command line (as administrator)

  5. Type: net stop apache2.2 (or whatever your service name is for apache)

  6. Now type in (or copy-paste) the same command as is used in the start menu shortcut above into the command line but make the following change to it; "C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin\httpd.exe" -D "__DEV__" -w -n "Apache2.2" -k config

  7. Note the change of the word start to config. What this magical command does is saves the settings you are seeing on the screen to the settings stored with the service in Windows. Hit Enter. From this point forward your variable will be passed whenever you start the service, the Apache Services Monitor starts the service, or windows starts the service.

Sorry for the novel everyone, I hope it helps some other weary soul out there to have all this info summarized and explained, I know it would have helped me! :D