A tutorial on web folder protection using htaccess / 文件夹密码保护

This is a beginner’s note on how to protect files in a folder on a web server running Apache. In brief, we need to provide two pieces of information in the right places for a password checking system, and one additional piece to make it work nicely.

As a running example, we assume
[code]
[your-home-directory]/public_html/secret/*
[/code]
needs protection. Note this also includes all sub-directors therein. Put it simply, if you download this package, then

  1. replace the [your-home-directory] with the actual path in “htaccess.txt”.
  2. upload “htaccess.txt” as [code][your-home-directory]/public_html/secret/.htaccess[/code]
  3. upload “secret_passwd.txt” (or create your own one) as [code][your-home-directory]/passwords/secret_passwd[/code]
  4. upload “no_access_to_secret.txt” as [code][your-home-directory]/public_html/error_doc/no_access_to_secret.html[/code]

then all files in[code]http://[your-domain-name]/secret/[/code] are password protected. When the browser asks for login, use
[code]user-id: foo
password: 123[/code]
will allow access. Please note that, lest invoking unnecessary operations when you open those files, I use .txt extension for all of them. You must rename them on your host machine to let the system work properly.

Let us explain the steps. First, before handling your files to a stranger’s browser, Apache checks whether there is a need for access control. If there is file named “.htaccess” (notice there is a dot at the beginning), Apache will follow rules listed in the file. For basic protection, the file that you have saved as “~/public_html/secret/.htaccess” has the following rules:
[code]
AuthType Basic
AuthName “[identifier]”
require valid-user
AuthUserFile “[full-path-to-a-user-password-file]”
[/code]
(The file is plain text. You can use any format-less text editor to create or edit it.)

The line of AuthType Basic explains itself. For “Basic” authorisation, Apache finds user / password combinations in a file saved on the location specified below. More sophisticated methods, e.g. by referring a database, are also possible. But for simplicity, we will use the Basic rule.

AuthName “[identifier]” has two roles for most browsers: (i) the browser will prompt the user with this string when asking for a log-in, and (ii) if the log-in proceeds successfully, the browser will remember the log-in with respect to this identifier for a while, so the user is not constantly bothered.

AuthUserFile [full-path-to-a-user-password-file] specifies where we put the second piece of information, i.e. the file containing the users and their passwords. The file should not be created manually, because the password needs to be encrypted. If you can log-in to your host machine (or you use your own machine, in which case, this tutorial might be too shallow for you anyway), you can use “htpasswd” to create your password file or add user-password entry to it:
[code]
htpasswd passwd-file user-name
[/code]
It will ask you for a password for the user. If you don’t have access to a command line console of your host machine, you can google “htpasswd generator”. A useful website is
[code]
http://www.htaccesstools.com/htpasswd-generator/
[/code]
For example, if you enter user “foo” and password “123”, it will return
[code]
foo:$apr1$5OZOdymB$R0iVstCnCi6gkymmlowrr.
[/code]
Note there is a period at the last of the password. Then you can add this line to a text file and upload it to the server.

By now, the password protection should work, however, in an unfriendly way. If an unauthorised user happens to land on a web page, which tries to access multiple protected files, the client browser will pop up a series of annoying log-in dialog boxes before it fails to load the contents. So we need to re-direct the client browser to a more informative page, if the login fails, e.g. one that tells how to contact you for access, etc. So we add this line
[code]
ErrorDocument 401 /error_doc/no_access_to_secret.shtml
[/code]
Don’t forget there is a slash before “error_doc”. As the command suggests, it handles error 401, unauthorised access, and returns
[code]
~/public_html/error_doc/no_access_to_secret.shtml
[/code]
to the client browser. Note that the path to this file should be specified with respect to your “~/public_html/” directory, rather than the root directory on the server, because the client browser will reach this file thorough
[code]
http://www.yourdomain.name/error_doc/no_access_to_secret.shtml
[/code]
and http://www.yourdomain.name/ <==> ~/public_html/

本站的网络相册有一个基本的密码保护。因为相册并不是WordPress的一部分,我研究了一下怎样对运行Apache系统的服务器上的一个文件夹设置密码保护,这里是一个初学者笔记。简单地说,如果你下载这个文件,然后

  1. 把里面所有的[your-home-directory]替换成你的根目录的路经。
  2. 把”htaccess.txt”上传成为[code][your-home-directory]/public_html/secret/.htaccess[/code]也就是你想保护的那个文件夹。不要忘记:改文件名成为.htaccess是必要的。我把所有的文件存为txt是为了方便编辑和研究。
  3. 把”secret_passwd.txt”上传到[code][your-home-directory]/passwords/secret_passwd[/code]
  4. 把”no_access_to_secret.txt”上传成为[code][your-home-directory]/public_html/error_doc/no_access_to_secret.html[/code]

那么目录[code]http://[your-domain-name]/secret/[/code]中的所有文件(包含子目录及其下属文件)就都会被密码保护起来。用户名和密码是:
[code]user-id: foo
password: 123[/code]

这个密码系统比较直观,作为Apache的新手,我们可以从”htaccess.txt”这个文件的内容猜出它的工作原理,将来可以加以改进。[code]AuthType Basic[/code]是说验证(Authentication)方式(Type)是“基本(Basic)”的。这个“基本方式”就是说,你会在下面告诉Apache系统去那里找一个文件,文件里面存着所有的用户和密码,以及哪些用户可以访问。

[code]AuthName “[identifier]”[/code]里面这个identifier是你向访问者提问的问题,比如“橘子的相册密码是什么?”注意这个问题会被对方的浏览器记下来,在一定时间限制内再次提问对方的浏览器会自动回答这个问题,这样就避免了访问一个有100张照片的相册就需要提问100次这样尴尬的情况。这个时间限制应该是可以与对方的浏览器协商的。但是在这里我们先不要走题,再说我也不会:)

[code]AuthUserFile “[full-path-to-a-user-password-file]”[/code]是告诉Apache去哪里找密码本本。如果你要修改我的例子,注意两条。第一这个密码本本自己也是个需要被翻出来看的文件,所以不要把它放在被保护的那个文件夹里面,让它本身也被密码保护起来。否则你就设置了一条死循环的规则,类似于:“办理二代身份证需要在户口所在地,迁入户口要用二代身份证”,又不是公安,咱们不要这么牛气。第二不要放在可以被公共访问的地方,也就是说,你要让它可以被访问,但是只能被Apache在需要的时候访问。所以最好就是放在你的网站根目录(一般是你的用户目录下面的那个”public_html/”)的上层。

[code]require valid-user[/code]这个就是说任何一个密码本里面列出来的用户都可以。你可有修改它,让只有一部分用户可以访问。

[code]ErrorDocument 401 /error_doc/no_access_to_secret.shtml[/code]是说要是访客没有权限,可以跳走,去显示一个你制定的错误信息。除了像本站这样,把出错提示变得萌一点以外,它的重要的用途在于某个页面上包含多条受保护的信息的情况(比如我们的相册的概览图上就有很多小图),这时如果一个无意的访客闯进来,浏览器可以在第一次授权失败的时候就把她/他带离受保护的区域,避免那个登录对话框反复去烦恼这个访客。

简单的加密原理就是这样啦。我下一步想用从数据库读取用户信息的方式来授权。这样的安全性据说不如现在这种简单的方式,但是可以有机地跟WordPress本身的用户系统结合起来。如果资深行家有耐心看到了这里,还请指教。

感谢阅读。

大梨