在專業的 Web 月台上,常常會需要使用者的帳號及密碼,也就是身分確認的動作。早期的 NCSA httpd 服務器並沒有提供這項使用者確認的功能,Webmaster 只能用手工打造一個身份確認的 CGI 程式。
自 CERN httpd 之後的 Web 伺服器大部份都提供了使用者身分確認的功能。僅管每套 Web 服務器的設定都不太相同,但在設定上都大同小異。
以下是 Apache 伺服器上的使用者身分確認的設定。
AuthType Basic
AuthName MyMember
AuthUserFile POST>
require valid-user
這個帳號密碼檔 /usr/local/MyMember.txt 的樣子可能如下例。其中冒號前面的字串是使用者帳號,冒號之後的字串是經過不可還原加密的密碼,編碼一般都是使用傳統的DES 編碼,密碼的頭二個字是類似種子的字符(salt),本例中都是3P。每行代表一位使用者。當然 Webmaster 要自行控制重覆帳號的情形。比較特殊是在 Win32 系統上架 Apache 的情形,冒號後的密碼不可加密,因為 Win32 沒有提供這方面的編碼
API,因此使用者密碼以明碼的方式存在。
john1234:3PWudBlJMiwro
queenwan:3PFNVLNPN9W0M
noname00:3PEsXaJx5pk7E
noname00:3PEsXaJx5pk7E
noname00:3PEsXaJx5pk7E
noname00:3PEsXaJx5pk7E
noname00:3PEsXaJx5pk7E oot:3PIt0snI6.84E
sun_moon:3PvymMeNOc.x.
nobody38:3PbskPKwV94hw
在Apache 1.3.6 版上,可以用~apache/bin/htpasswd 來產生單筆的帳號及密碼,但對於需要大筆資料的商業站台,可能就需要自行寫程式來處理了。 UNIX 上需要呼叫 crypt() 來處理編碼。
一切都設定好了之後,連線時就會在瀏覽器出現核對密碼的視窗,如上圖就是SEEDNet 的 MySEED 網站的使用者核對機制。在輸入了帳號及密碼後,瀏覽器會將它用BASE64 編碼後,傳到伺服器端。當然BASE64 只是編碼不是加密,因此在網路上這種傳輸的安全性仍然不高,還是有可能被中間的劊客截下,再將BASE64 還原,這也是整個用戶認證中最美中不足的地方,或許日後支援摘要認證(Digest) 及使用MD5 編碼後,可以解決此問題。之後每一頁仍然需要帳號及密碼,只不過瀏覽器會幫你主動送出,不用再輸入帳號密碼了。這方面瀏覽器會保留到關閉為止,下次重執行瀏覽器仍需輸入第一次。
在使用者數量少時,使用上述的方法輕鬆又省事。但在使用者有數萬人,甚至數十萬人時,會發生整個伺服器的效率都被搜尋帳號密碼下拖垮,可能讀取一頁需要數十秒到數分鐘。這種情形再使用伺服器提供的密碼查核機制就不太明智了。在Netscape Enterprise Server 上可能就可以使用 NSAPI 來開發自己的核對方式,在IIS 上也可以用 ISAPI 過濾器開發。寫 C/C 程式呼叫 NSAPI/ISAPI 總是很累,在PHP 上有了另外的選擇,這也是本節的主題。
PHP 的 HTTP 相關函式庫提供了 header() 的函數。許多 Web 伺服器與客戶端的互動,都可以使用這個函數來變戲法。例如在某個 PHP 頁面最開始處,也就是第一行或第二行,加入以下的程序,可以將使用者重導到作者的網頁。
header("Location: http://wilson.gs");
exit;
?>
exit;
?>
exit;
?>
,在上述程式之後的HTML 文字或是PHP 程式都永遠不會出現在使用者端了。
同樣的道理,我們就用 header() 來變成使用者認證的把戲。可以在 PHP 的最開頭送出字符串到使用者端,就會在使用者端出現下圖的視窗。
Header("WWW-Authenticate: Basic realm="Member"");
Header("HTTP/1.0 401 Un Header("HTTP/1.0 401 Unhorized"); 在程式中字符串realm="Member" 中的Member 字樣出現在圖中,當然若使用中文字取代,瀏覽器端也會出現中文字,如上面的MySEED 圖。若 Web 站台使用者還有它語文,如英文或日文,送出中文的 realm 字串似乎就比較不合適。無論如何,這都要視月台的性質及使用者定位而決定。
當然這還是很粗糙,因為除了送出視窗後,就沒有下文了,帳號輸入正確也好,輸入錯誤也罷,都不會有任何的結果。我們需要再更進階的程式來處理。
在後端的使用認證上,考慮使用資料庫作為儲存帳號及密碼的後端,在這種架構可以容納許多的使用者,管它一萬個使用者還是十萬個使用者。若您的站已有數十萬個使用者帳號,那麼恭喜您,您的站算是世界級的大站了。 MySQL 是個不錯的選擇,許多站台,甚至是商業化的站台都用它來做後端的資料庫。當然您要架真正的商業月台,錢不是問題的話,那可以使用口碑最廣的 Oracle 資料庫系列。
要在 PHP 中使用任何資料庫,都要先將資料庫的伺服器端及客戶端設定好,之後再編譯 PHP 及 Apache 系統。
準備好 MySQL 及 PHP 之後,先在 MySQL 中加入新的資料庫,本例是加入mymember,用別的名字當然也可以。 MySQL 加入資料庫 (Database) 很容易,只要在MySQL 存放 Database 的地方 mkdir 就可以了。例如在 UNIX Shell 下打
hahaha:/usr/local/mysql/data# mkdir mymember
建立了資料庫之後,尚需要建立資料表格 (Table) 方能使用。設定的表格如下,可以將它儲存在/tmp/memberauth.sql 中
CREATE TABLE MemberAuth (
Serial mediumint(9) NOT NULL auto_increment, 8
Enable char(1) DEFAULT '0' NOT NULL,
PRIMARY KEY (Serial) memberauth.sql
先看看memberauth.sql 的這些欄位。 Serial 是個自動增加的整數欄位,每輸入一筆資料,就會自動加一,這當然不能是空的欄位,於是就用 NOT NULL 了。第二個欄位是 Username,代表使用者的帳號,為了統一以及適應各系統起見,設定成八個字,當然這個欄位也不能是空的。 Password 是第三個欄位,為使用者的密碼。第四個欄位 Enable 做為帳號是否有效的旗標,設計上 0 表示無用,1 表可用,日後還可加入其它值做不同的用途。
設計了資料表之後,就要將資料表加入資料庫了。由於常要使用 MySQL 資料庫,可以到 http://www.phpwizard.net/phpMyAdmin 下載 phpMyAdmin,使用瀏覽器操作管理 MySQL,輕鬆又方便。若使用這套 phpMyAdmin 可以在它的使用者介面上輸入memberauth.sql 加入 MySQL 中。或者也可以在 UNIX Shell 下輸入下式,也是有同樣的效果。
mysql mymember
準備好了之後,就可以輸入使用者帳號及密碼在 memberauth 資料表中了。當然還是使用 phpMyAdmin 方便,用 mysql 程式就要一筆筆的 INSERT 了。
接著進入了設計函數的階段了。
file://---------------------------
/ / 使用者認證函數auth.inc
// Author: Wilson Peng
// Copyright (C) 1999
file://--------------- ------------
$error401 = "/home/phpdocs/error/401.php";
if ($PHP_AUTH_PW=="") {
Header(" WWW-Authenticate: Basic realm="超金卡會員"");
Header("HTTP/1.0 401 Unauthorized");
include($error401); Š
$db_id = mysql_pconnect("localhost", "myid", "mypw");
$result = mysql_db_query("mymember","select emberpassword, enable"","select $PHP_AUTH_USER'");
$row = mysql_fetch_array($result);
$MemberPasswd = $row[0];
$M>$MemberPasswd = $row[0];
$MumEnable = $row[1]; $MemberEnable==0) {
echo "您的帳號停用了";
exit;
}
if ($PHP_AUTH_PWPW=$ ("WWW-Authenticate: Basic realm="超金卡會員"");
Header("HTTP/1.0 401 Unauthorized");
include($error401);
}
?>
Copyright (C) 1999, Wilson Peng
要使用這個auth.inc,每個PHP 的第一行加入 ? require("auth.inc"); ?> 。
在加入本程式的 PHP 檔案都會檢查帳號密碼,圖片等就不會檢查,比起使用 Web 服務器功能的某目錄下全都檢查,PHP 顯得有彈性多了。
$error401 = "/home/phpdocs/error/401.php";
這行表示在使用者按下取消,或檢查失敗時,要顯示給使用者看的檔案。
if ($PHP_AUTH_PW=="") {
Header("WWW-Authenticate: Basic realm="超金卡會員"");
Header("HTTP/1.0 401 Unhorhorized" );
include($error401);
exit;
} else
到else 之前,並沒有傳入密碼視窗的密碼視窗。其中的
$PHP_AUTH_USER、$PHP_AUTH_PW 是 PHP 中特殊的變數,分別代表使用者確認的帳號及密碼。上面的程式也是利用這二個變數來處理使用者認證。
$db_id = mysql_pconnect("localhost", "myid", "mypw");
$result = mysql_db_query("mymember","select password, enable from @ $PHP_AUTH_USER'");
$row = mysql_fetch_array($result);
$MemberPasswd = $row[0];
$M>$MemberPasswd = $row[0];
$Mhidable = $ >若使用者有輸入帳號及密碼,則向資料庫查詢。同時檢查該用戶是否仍可使用。
if ($MemberEnable==0) {
echo "您的帳號停用了";
exit;
}
上四行程式為帳號被停用的情形。
if ($PHP_AUTH_PW!=$MemberPasswd) {
Header("WWW-Authenticate: Basic realm="超金卡會員"");hor
Header("HTTP/1 4011" );
include($error401);
exit;
}
密碼錯誤則再次要求使用者輸入帳號及密碼。
實際使用時,可以視需要加入的網頁再加入 auth.inc 這個檔案,就不用連看張圖形也要查一次密碼,降低服務器和用戶二端的資源。當然,和 MySQL 的連繫上,可以使用 mysql_pconnect() 一直和 MySQL 服務器連線。或是使用mysql_connect() 每次重新連線,用這個函數要記得早點使用 mysql_close() 將資料庫關閉。下面的程序 auth1.inc 是另一個版本的認證程序,就是開啟連線後馬上關閉,釋放資源的範例。
file://---------------------------
/ / 使用者認證函數-1 auth1.inc
// Author: Wilson Peng
// Copyright (C) 1999
file://------------- --------------
$error401 = "/home/phpdocs/error/401.php";
if ($PHP_AUTH_PW=="") {
Header ("WWW-Authenticate: Basic realm="超金卡會員"");
Header("HTTP/1.0 401 Unauthorized");
include($error401); else {
$db_id = mysql_connect("localhost", "myid", "mypw");
$result = mysql_db_query("mymember","select🎜>$result = mysql_db_query("mymember","select🎜>$result = mysql_db_query("mymember","select🎜>$result = mysql_db_query("mymember","select 密碼='$PHP_AUTH_USER'");
$row = mysql_fetch_array($result);
$MemberPasswd = $row[0];
$Member]Enable[11]Enable; mysql_close($db_id);
if ($MemberEnable==0) {
echo "您的帳號停用了";
exit;
}
exit;
} Header("WWW-Authenticate: Basic realm="超金卡會員"");
Header("HTTP/1.0 401 Unauthorized"); );
exit;
}
}
?>
http://www.bkjia.com/PHPjc/316617.html
www.bkjia.com
true