📚 What is the .htpasswd file
The .htpasswd is a text file that stores the usernames and passwords your server uses to protect a folder or a whole site with HTTP basic authentication: the little browser prompt that asks for a username and password before showing anything. Apache reads it (mod_auth_basic and mod_authn_file) and so does nginx (auth_basic).
It has one line per user, with the name and the encrypted password separated by a colon:
admin:$2y$10$Yh2b… maria:$apr1$Qx8… client:$6$k3…
The server never stores the password, only its hash: when someone logs in, it hashes what they typed with the same method and compares. That is why each line can use a different method: the prefix ($2y$, $apr1$, $6$, {SHA}) tells the server which one.
🧭 How it works under the hood
- The browser requests the page and the server answers
401 Unauthorizedwith the headerWWW-Authenticate: Basic realm="…". - The browser shows the prompt and from then on sends, with every request, the header
Authorization: Basic …with the username and password in Base64. - Base64 is not encryption, just an encoding: anyone who intercepts the traffic can read it. Always use it over HTTPS.
🎯 What it is for (and how it relates to SEO)
- Test or staging environments. It is the safest way to keep a copy of your site out of Google: Googlebot gets a 401 and cannot read anything. A
Disallowin robots.txt does not stop a URL from being indexed, and anoindextag requires letting it be crawled; a password cuts both off at the root. - Sites under development before launch, or private areas for clients.
- An extra layer in front of
wp-login.phpor/wp-admin/in WordPress, to stop brute-force attacks before they reach PHP.
⚠️ If you protect a site that is already live, Google will no longer be able to crawl it and, over time, its pages will drop out of the index. And when you launch a site that was protected, remember to remove the password.
🔐 Which encryption to choose
| Encryption | Prefix | Apache 2.4 | nginx | Security |
|---|---|---|---|---|
| bcrypt | $2y$ | ✅ | ✅ through the system crypt() (current Linux) | 🟢 The best: slow on purpose, adjustable cost |
| APR1-MD5 | $apr1$ | ✅ (the htpasswd default) | ✅ | 🟡 Acceptable; fast to attack with GPUs |
| SHA-512 crypt | $6$ | ✅ on Linux · ❌ on Windows | ✅ | 🟢 Good, salted with thousands of rounds |
| SHA-1 | {SHA} | ✅ | ✅ | 🔴 No salt: only as a last resort |
If you do not know which server you have, bcrypt is the default choice and APR1-MD5 the one that works everywhere. They match htpasswd -B and htpasswd -m on the command line; SHA-512 is what openssl passwd -6 produces.
📁 Where to put the file
- Outside the public folder (for example
/home/user/.htpasswd, next topublic_html, not inside it). That way nobody can download it even if the configuration fails. - The path in
AuthUserFile(Apache) andauth_basic_user_file(nginx) must be absolute. - Apache blocks files starting with
.htby default; nginx does not, which is why its snippet includes the block that denies them. - After editing the nginx configuration you must reload it (
nginx -tandsystemctl reload nginx); Apache applies the.htaccessimmediately.