不编写PHP脚本,也可以得到与程序清单17-4非常类似的结果。
Apache Web服务器包含一些不同的身份验证模式,这些模式可以用于判断用户输入数据的有效性。最简单的是使用mod_auth,它将用户名-密码对与服务器中一个文本文件中的行进行比较。
要获得与前面脚本相同的输出结果,必须创建两个不同的HTML文件,一个用来显示成功登录后的内容,另一个用来显示拒绝页面。我们将跳过前例中一些HTML元素,但是真正生成HTML的时候还需要包括<html>和<body>标记。
程序清单17-5包含了经过身份验证后的用户可以看到的内容。该文件名称为content.html。程序清单17-6包含了用户身份验证失败后的拒绝页面内容。文件名称为rejection.html。出错的时候是否显示一个网页是可选的,但是如果在显示的网页中放一些有用的东西,未尝不是一个很好的专业化做法。对于一个用户试图进入保护区域但是被拒绝而显示的网页,有用的内容可能包括如何注册一个密码,或在遗忘密码的情况下,如何通过电子邮件重设密码的说明。
程序清单17-5 content.html——示例内容
<html><body>
<h1>Here it is!</h1>
<p>I bet you are glad you can see this secret page.</p>
</body></html>
程序清单17-6 rejection.html——401错误的示例页面
<html><body>
<h1>Go Away!</h1>
<p>You are not authorized to view this resource.</p>
</body></html>
在这些文件中,并没有什么新的内容。在这个例子中,唯一一个有趣的文件是程序清单17-7给出的页面。该文件需要调用.htaccess,它将控制对目录中任何文件和子目录的访问。
程序清单17-7 .htaccess——.htaccess文件可以设置许多Apache配置,包括是否激活身份验证
ErrorDocument 401/chapter17/rejection.html
AuthUserFile/home/book/.htpass
AuthGroupFile/dev/null
AuthName/"Realm-Name/"
AuthType Basic
require valid-user
程序清单17-7是一个.htaccess文件,用于在一个目录中开启基本身份验证功能。可以在.htaccess文件中修改许多设置,但是在这个例子中,我们所做6行修改都与身份验证有关。第一行:
ErrorDocument 401/chapter17/rejection.html
将告诉Apache对验证失败的访问者显示什么样的文档(HTTP错误号401)。可以使用其他的ErrorDocument指令来提供不同的HTTP错误(例如,404)所需的页面。其语法如下所示:
ErrorDocument error_number URL
对于一个处理错误401的页面,给定的URL可以被公共访问是非常重要的。如果页面锁定在一个目录里,在该目录中访问者需要成功通过验证才能浏览页面,那么提供一个自定义的错误页面告诉人们身份验证失败并不是非常有意义的。
这一行:
AuthUserFile/home/book/.htpass
将告诉Apache在什么地方可以找到包含已经通过身份验证的用户的密码文件。通常,这个文件是.htpass,但是我们可以给它取任何自己更喜欢的名字。文件的名称不重要,重要的是保存该文件的位置。该文件不应保存在Web树目录中——因为保存在Web树目录中的话,人们可以通过Web服务器下载它。在这个例子中,我们给出.htpass示例文件,如程序清单17-8所示。
与指定通过身份验证的单个用户一样,指定只有在特定组中通过身份验证的用户才能访问资源也是可能的。我们选择不这样做,因此这行:
AuthGroupFile/dev/null
可以将AuthGroupFile设置为指向/dev/null,这是UNIX系统中一个特殊的文件,可以保证该文件为空。
与PHP示例一样,要使用HTTP身份验证,需要命名保护区域,如下所示:
AuthName/"Realm-Name/"
可以根据自己的喜好选择任意的区域名称,但是必须记住将该名称向访问者显示。为了明显起见,我们将示例中的名称改为/"Realm-Name/"。
因为Apache支持许多不同的身份验证方法,必须指定使用哪一种身份验证方法。这里,我们使用的Basic身份验证方法是通过如下指令指定的:
AuthType Basic
需要指定允许访问的访问者。我们可以指定特定用户、特定组,或者就像这个例子一样,只简单地允许通过身份验证的用户进行访问。代码行:
require valid-user
指定了任何有效用户都可以访问。
程序清单17-8 .htpass——密码文件存储用户名和已加密的密码
user1:0nRp9M80GS7zM
user2:nC13sOTOhp.ow
user3:yjQMCPWjXFTzU
user4:LOmlMEi/hAme2
.htpass文件中的每一行都包含一个用户名、冒号和该用户的加密密码。
你的.htpass文件的确切内容会有所不同。要创建它,可以使用一个名为htpasswd的小程序,该程序包含在Apache软件包中。
htpasswd程序用于下列两种方法之一:
htpasswd[-cmdps]passwordfile username
或者
htpasswd-b[cmdps]passwordfile username password
唯一使用的开关是-c。使用-c可以告诉htpasswd创建文件。必须在第一个添加的用户中使用这个开关。将它用于其他用户的时候要小心,因为如果该文件存在,htpasswd将删除这个文件并创建一个新文件。
该程序的可选项m、d、p或s开关可以用来指定使用哪种加密算法(包括不加密)。开关b告诉程序要期望密码作为它的参数,而不提示输入密码。如果要作为批处理的一部分交互地调用htpasswd,这个开关就是有意义的,但是如果从命令行调用htpasswd,就不应该使用它。
下列命令创建如程序清单17-8所示的文件:
htpasswd-bc/home/book/.htpass user1 pass1
htpasswd-b/home/book/.htpass user2 pass2
htpasswd-b/home/book/.htpass user4 pass3
htpasswd-b/home/book/.htpass user4 pass4
请注意,htpasswd可能没有包含在路径中:如果没有,可能需要提供其完整路径。在许多系统中,可以在/usr/local/apache/bin目录下找到它。
这种类型的身份验证容易建立,但是按照这样的方法使用.htaccess文件还存在一些问题。
用户和密码保存在同一个文本文件中。在浏览器每次请求一个被.htaccess文件保护的文件时,服务器都必须解析.htaccess文件,然后再解析密码文件,以试图匹配用户名和密码。不使用.htaccess文件,我们可以在httpd.conf文件中指定同样的事情——httpd.conf文件是该Web服务器的主配置文件。在每次请求一个文件的时候,系统都要解析.htaccess文件。而httpd.conf文件只在服务器启动的时候解析。这样速度将更快,但是也意味着,如果要做修改,需要停止并重新启动服务器。
无论将服务器指令保存在什么地方,对于每次请求,都要搜索密码文件。这就意味着,它与其他使用普通文件的技术一样,对于成千上万的用户来说,这种方法也是不合适的。