For many of our projects, the .htaccess file is under version control… but at the same time, I need to put HTTP Basic Authentiation on just the staging site. Unfortunately the host weren’t able to do this for me, but with a little .htaccess trickery I was able to detect the staging site URL and trigger the authentication.
Why do I want to do this? Well, pretty often the client is keen to see how some new, embargoed, content is going to fit together, whether that’s a group of new pages or a new masthead, etc. I don’t want just anyone guessing my staging site URL and wandering around getting information they shouldn’t!
The key, as is often the case, was in a Stack Overflow post. Let me walk you through the specifics:
# Detect the domain host and set an environment var for staging SetEnvIf Host staging\.somewhere\.com$ TRS_IS_STAGING Order deny,allow # Detect the staging environment var Deny from env=TRS_IS_STAGING Satisfy any AuthType Basic AuthName "Nothing to see here. Move along, please" # We rely on this rule only being applied on staging, # as it will break everywhere else AuthUserFile /nas/wp/www/staging/promotone/.htpasswd Require valid-user # Hide the htpasswd file <Files .htpasswd> Order allow,deny Deny from all Satisfy All </Files>
The first block of the file uses a simple regex to check if the Host
environment variable ends with staging.somewhere.com, and if it does it sets a further environment variable called TRS_IS_STAGING. The config is then set to Deny
any request where the TRS_IS_STAGING environment variable is set. Because Satisfy any
is present, Apache will then attempt to use the Basic Authentication set in the next few lines with AuthType
, AuthName
, AuthUserFile
.
Note that the AuthUserFile
directive needs a filepath which is either absolute or relative to the ServerRoot, either way it’s pretty specific to the server setup. That’s fine in this case, but you would need to differentiate between each server setup and the path for it if you wanted to add authentication to more than one server.
Lastly, I’m hiding the .htpasswd; it’s not ideal that it’s web available (i.e. in the DocumentRoot) but that’s the limitations of the hosting environment I’m dealing with.