使用者在設計和維護網站的時候,經常需要限制對某些重要文件或資訊的存取。通常,我們可以採用內建於WEB伺服器的基於HTTP協定的使用者驗證機制。當訪客瀏覽受保護頁面時,用戶端瀏覽器會彈出對話方塊要求使用者輸入使用者名稱和密碼,並對使用者的身分進行驗證,以決定使用者是否有權存取頁面。下面用兩種方法來說明其實作原理。
一、用HTTP標頭來實作
標頭是伺服器以HTTP協定傳送HTML資訊到瀏覽器前所送出的字串。 HTTP採用一種挑戰/回應模式對試圖進入受密碼保護區域的使用者進行身份驗證。具體來說,當使用者首次向WEB伺服器發出存取受保護區域的請求時,挑戰進程被啟動,伺服器會傳回特殊的401標頭,表示該使用者身分未經驗證。用戶端瀏覽器在偵測到上述回應之後會自動彈出對話框,要求使用者輸入使用者名稱和密碼。使用者完成輸入之後點選確定,其身分識別資訊就傳送到服務端進行驗證。如果使用者輸入的使用者名稱和密碼有效,WEB伺服器將允許使用者進入受保護區域,並且在整個存取過程中保持其身分的有效性。相反,若使用者輸入的使用者名稱或密碼無法通過驗證,客戶端瀏覽器會不斷彈出輸入視窗要求使用者再次嘗試輸入正確的資訊。整個過程將持續到使用者輸入正確的資訊位置,也可以設定允許使用者進行嘗試的最大次數,超出時將自動拒絕使用者的存取要求。
在PHP腳本中,使用函數header()直接給客戶端的瀏覽器發送HTTP標頭,這樣在客戶端將會自動彈出使用者名稱和密碼輸入窗口,來實現我們的身份認證功能。在PHP中,客戶端使用者輸入的訊息傳送到伺服器之後自動儲存在$PHP_AUTH_USER,$PHP_AUTH_PW,以及$PHP_AUTH_TYPE這三個全域變數中。利用這三個變量,我們可以根據保存在資料檔案或資料庫中使用者帳號資訊來驗證使用者身分!
不過,需要提醒使用者註意的是:只有在以模組方式安裝的PHP中才能使用$PHP_AUTH_USER,$PHP_AUTH_PW ,以及$PHP_AUTH_TYPE這三個變數。如果使用者使用的是CGI模式的PHP則無法實現驗證功能。在本節後面附有PHP的模組方式安裝方法。
下面我們用Mysql資料庫來儲存使用者的身分。我們需要從資料庫中提取每個帳號的使用者名稱和密碼以便與$PHP_AUTH_USER和$PHP_AUTH_PW變數進行比較,判斷使用者的真實性。
首先,在MySql建立一個存放使用者資訊的資料庫
資料庫名為XinXiKu ,表名為user;表格定義如下:
create table user(
ID INT(4) NOT NULL AUTO_INCREMENT,
name VARCHAR(8) NOT NULL,
password CHAR(8) NOT NULL,
PRIMARY KEY(ID)
)
說明:
1、ID為序號,不為零且自動遞增,為主鍵;
2、name為使用者名,不能為空;
3、password為使用者密碼,不能為空;
以下是使用者驗證檔案login. php
//判斷使用者名稱是否設定
if(!isset($PHP_AUTH_USER)) {
header("WWW-Authenticate:Basic realm="身份驗證功能"");
header("HTTP/1.0 401 Unauthorized");
echo "驗證失敗,您無權共享網路資源!";
exit();
}
/*連接資料庫*/
$db=mysql_connect("localhost","root","");
//選擇資料庫
mysql_select_db("XinXiKu",$db);
//查詢使用者是否存在
$result=mysql_query("SELECT * FROM user where name='$PHP_AUTH_USER' and password='$PHP_AUTH_PW'",$db);
if ($myrow = mysql_fetch_row($result)) {
//以下為身份驗證成功後的相關操作
……
} else {
//身份驗證不成功,提示使用者重新輸入
header("WWW-Authenticate:Basic realm="身份驗證功能"");
header("HTTP/1.0 401 Unauthorized");
echo "驗證失敗,您無權共享網路資源!";
exit();
}
?>
程式說明:
在程式中,先檢查變數$PHP_AUTH_USER是否已經設定。如果沒有設置,說明需要驗證,腳本發出HTTP 401錯誤號頭標,告訴客戶端的瀏覽器需要進行身份驗證,由客戶端的瀏覽器彈出一個身份驗證窗口,提示用戶輸入用戶名和密碼,輸入完成後,連接資料庫,查詢該用使用者名稱及密碼是否正確,如果正確,允許登入進行相關操作,如果不正確,繼續要求使用者輸入使用者名稱和密碼。
函數說明:
1、isset():用於確定某個變數是否已被賦值。根據變數值是否存在,傳回true或false
2、header():用於傳送特定的HTTP標頭。注意,使用header()函數時,請務必在任何產生實際輸出的HTML或PHP程式碼前面呼叫該函數。
3、mysql_connect():開啟MySQL 伺服器連線。
4、mysql_db_query():送查詢字串(query) 到MySQL 資料庫。
5、mysql_fetch_row():傳回單列的各欄位。
二、用session實作伺服器驗證
對於需要驗證的頁面,使用apache伺服器驗證是最好不過的了。但是,apache伺服器驗證的介面不夠友善。而且,cgi模式的php,iis下的php,都不能使用apache伺服器驗證。這樣,我們可以利用session在不同頁間保存使用者身份,達到身份驗證的目的。
在後端我們同樣利用上面的Mysql資料庫存放用戶資訊。
我們先寫一個使用者登入介面,檔案名稱為login.php,程式碼職下:
____________________________________________________________
<form action="login1.php">
使用者名稱:<input type="text" name="name"><br>
口令:<input type="text" name="pass"><br>
<input type="submit" value="登入">
</form>
____________________________________________________________
login1.php處理提交的表單,程式碼如下:
$db=mysql_connect ("localhost","root","");
mysql_select_db("XinXiKu",$db);
$result=mysql_query("SELECT * FROM user where name='$name' and password='$pass'",$db);
if ($myrow = mysql_fetch_row($result)) {
//註冊用戶
session_start();
session_register("user");
$user=$myrow["user"];
// 身份驗證成功,進行相關操作
……
} else {
echo"身份驗證失敗,您無權共享網路資源!";
}
?>
這裡要說明的是,使用者可以使用在後續的操作中使用**http://domainname/next.php?user=使用者名稱**來繞過身份驗證。所以,後續的操作應先檢查變數是否註冊:已註冊,則進行對應操作,否則視為非法登入。相關程式碼如下:
session_start();
if (!session_is_registered("user")){
echo "身分驗證失敗,屬於非法登入!";
} else {
//成功登入進行相關操作
……
}
?>
附錄:PHP以模組方式安裝方法
1、先下載檔案:mod_php4-4.0.1-pl2。 [如果你的不是PHP4,那就趕快升級吧!]
解開後有三個檔案:mod_php4.dll、mod_php4.conf、readme.txt
2、相關檔案拷貝
把mod_php4.dll拷貝到apache安裝目錄的modules目錄下面
把mod_php4.conf拷貝到apache安裝目錄的conf目錄下面
把msvcrt.dll文件拷貝到apache的安裝目錄下面
3、打開conf/srm.conf文件,在其中加上一句
Include conf/mod_php4.conf
在做這一些之前請把您的httpd.conf中關於CGI模式的所以設定語句都去掉,即類似下面的部分!
ScripAlias /php4/ "C:/php4/"
AddType application/x-httpd-php4 .php
AddType application/x-httpd-php4 .php3
AddType application/x-httpd-php4 .php4
Action application/x-httpd-php4 /php4/php.exe
要讓PHP支援更多的字尾名,沒問題。在給定的設定檔mod_php4.conf已經支援了三種後綴名php,php3,php4,如果你還想支援更多的後綴名可以更改這個文件,很簡單的。
4.測試
用<? phpinfo(); ?> 測試。會看到Server API的值為apache,而不是cgi ,還有有關HTTP Headers Information的資訊。