當訪問者瀏覽受保護頁面時,用戶端瀏覽器會彈出交談視窗要求使用者輸入使用者名稱和密碼,對使用者的身份進行驗證,以決定使用者是否有權訪問頁面。下面用兩種方法來說明其實現原理。
一、用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的資訊。