簡單的驗證碼機制
Mon, 24 Jul 2006 11:17:30 +0800為了自己網站改版,隨手寫了一個留言板。並且想了一個簡單的驗證碼機制,防止他人使用機器人在我的留言板亂倒東西。
由於是使用php,所以有一些方便的工具(GD、Session),可以整合出完整的功能。
我的想法如下:
- 驗證碼(check_code)存放在資料庫,用一個check_id作為key
- 留言板的留言與看留言的介面在同一個頁面,每次進入這個頁面時,驗證碼都要更換。所以不能直接使用session_id作為key
- 每次進入頁面時,會刪除舊的check_id,產生新的check_id,同時產生一組check_code存放在資料庫
- 用gd產生check_code的圖片,在輸入留言的form上面顯示
- 程式之間利用session來取得check_id,check_code不會在client端出現,所以可以確保一些安全性
以下簡述一下我的程式:
第一步還是要在資料庫中建立一個資料表(我用的是mysql),我取名叫做fsession:
CREATE TABLE `fsession` ( `check_id` varchar(40) NOT NULL default '', `check_code` varchar(8) NOT NULL default '00000000', PRIMARY KEY (`check_id`) ) TYPE=MyISAM;
接下來是產生check_id的code:
session_start(); $sql = sprintf("SELECT * FROM fsession WHERE check_id='%s'", $_SESSION['check_id']); $result = $db->query($sql); $tmp = $db->num_rows($result); if ($tmp > 0) {//如果有舊的check_id,就把他從資料庫刪掉 $sql = sprintf("DELETE FROM fsession WHERE check_id='%s'", $_SESSION['check_id']); $db->query($sql); } //接下來產生新的check_id以及check_code $_SESSION['check_id'] = md5(time().rand()); //上面產生check_id $sql = sprintf("INSERT INTO fsession (check_id, check_code) VALUES ('%s', '%s')", $_SESSION['checkid'], mt_rand(10000000,99999999)); //上面產生一組八位數的check_code $db->query($sql); //ok,存入資料庫
(這個方法不太好,因為我也不太確定不同字串產生的md5摘要是否會一樣.....不過因為摘要長度是一樣的,比較方便,所以先用了:D。也許應該用auto_increment的id比較好?只要改一下程式就可以了(先存入資料庫再取得check_id,但是check_id的type要改成int))
接下來是產生驗證碼圖片的程式(使用GD,幾乎從php manual上面的例子照抄....):
session_start(); if (!empty($_SESSION['check_id'])) { $sql = sprintf("SELECT check_code FROM fsession WHERE check_id='%s'", $_SESSION['check_id']); $result = $db->query($sql); if ($db->num_rows($result) == 0) { $code = "error! db"; } else { list($code) = $db->fetch_row($result); } } else { $code = "error! session"; } header("Content-type: image/jpeg"); //指定輸出內容的type $im = imagecreatefromjpeg("images/code_bg.jpg"); //用一張背景圖產生需要的背景 $color = imagecolorallocate($im, 32, 32, 32); //指定顏色 imagettftext($im, 12, 0, 2, 13, $color, "fonts/georgiai.ttf",$code); //利用true type字型來產生圖片 imagejpeg($im); //輸出所產生的圖片內容到瀏覽器 imagedestroy($im);
假設這一隻程式叫做authcode.php,只要在需要圖片的地方使用<img src="authcode.php">就可以顯示圖片。另外,字型檔案與字型大小需要依照系統做調整(也可以用ps、type1等字型,尤其是在linux系統上)
最後,只要在留言存入資料庫的地方,先檢查使用者輸入的檢查碼,與存在資料庫中的檢查碼比對,就可以確認。