Programster's Blog

Tutorials focusing on Linux, programming, and open-source

Htaccess Cheatsheet

Requre HTTP Basic Auth

This is the most common thing that one may need an htaccess file. Implementing a really basic username/password around a site so that you can't see any of it unless you plug in the details. This also works well for APIs though too.

AuthType Basic
AuthName "Protected Directory"
AuthUserFile "/var/www/my-site/.htpasswd"
Require valid-user

That would require a .htpasswd file at /var/www/my-site though, so don't forget to put one there, and make sure that is not a public area in your apache config.

Don't forget that you can implement HTTP Basic auth in the application layer with PHP, quite easily.

Apply To Specific Routes

Usually, I set the .htaccess file within a folder that needs protecting. However, if you wish to use this on something like a WordPress site for which you wish to protect a route/path (which isn't a folder), then you can use the following example to apply the authentication requirement to just that route(s).

# Do the regex check against the URI here, if match, set the "require_auth" var
SetEnvIf Request_URI ^/my/url/route require_auth=true

# Auth stuff
AuthUserFile /var/www/my-site/.htpasswd
AuthName "Password Protected"
AuthType Basic

# Setup a deny/allow
Order Deny,Allow

# Deny from everyone
Deny from all

# except if either of these are satisfied
Satisfy any

# An authenticated user
Require valid-user

# Or if the "require_auth" var is NOT set (any route that did not match our regex for routes requiring auth).
Allow from env=!require_auth

By tweaking your regular expression, you could match any number of routes.

Allow Certain Folders

If you want to block all folder except certain ones, read my post on Htaccess - Require Auth For Everywhere Except Whitelist.

Htpasswd

The htpasswd file can be used to list all the users and their hashed passwords, that should have access to the site. There should be one line for each user. E.g.

user1:$2y$05$5WwxMM7hsG0J4gbfQty1BOPO7xYp7NiGT3iq4TlnTRB7sZJDn49pa
user2:$2y$05$/ofEZc3e0w82TFLuIcptiuv9ifyUtFlk1cmV5logDYDabRlZEvBdC
user3:$2y$05$ozer.xrEfhWbnyJgzFgtS..XMip2cZeNasg6s3VNW9uwKlDXwBZsS

Even if two users have the same password, the password hash will look different (unless you literally copy/pasted them, which would be dumb).

To generate a line for a new user in the file, run the following script (swapping out the variables).

USERNAME="myUsername"
PASSWORD="myPassword"

htpasswd -Bbn $USERNAME $PASSWORD

Redirect To Index.php Except Existing Files And Directories

If you are using a PHP framework that implements a routing engine, you may wish for Apache to route all requests to index.php unless its for a file that already exists (e.g. a Javascript script file, or an image).

This is as easy as:

RewriteEngine On

# Don't redirect if matches file
RewriteCond %{REQUEST_FILENAME} !-f

# Don't redirect if matches directory
RewriteCond %{REQUEST_FILENAME} !-d

# Redirect everything else to index.php
RewriteRule ^ index.php [QSA,L]

Don't forget that you will need to enable the rewriting module in Apache with sudo a2enmod rewrite

Redirect HTTP to HTTPS

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]

This will use a temporary redirect. You may wish to switch the 301 to 302 for a permanent redirect for SEO rankings.

Validator

To perform of a basic check of your htaccess file for mistakes, you may wish to use htaccesscheck.com

References

Last updated: 12th September 2024
First published: 12th February 2021