Home Lập trình Web PHP Tạo mã bảo vệ (captcha) dùng PHP và AJAX
Tạo mã bảo vệ (captcha) dùng PHP và AJAX
Thứ sáu, 10 Tháng 10 2008 11:08

CAPTCHA, thường được gọi là mã bảo vệ, là một cách đơn giản nhất để kiểm tra xem người dùng chương trình là một máy tính hay là con người. Nó được dùng để ngăn chặn spam (thư rác) trên website. Nếu trên form nhập liệu bạn dùng CAPTCHA thì sẽ giúp chống được các trình bot, hoặc gây cản trở khi cách trình bot dùng form của bạn.

CAPTCHA là một đoạn văn bản ngẫu nhiên được ghi lên hình, với những ký tự và đường trang trí khác nhau, nhầm chống các máy phân tích ký tự. Dùng để kiểm tra khi form của bạn được Submit.

Bài hướng dẫn là khái đơn giản, nhưng nếu bạn không quen với AJAX thì có thể gặp một số khó khăn. Phần hướng dẫn này bao gồm một trang HTML để hiện form phía người dùng. Một file PHP để sinh CAPTCHA. Một file JavaScript để xử lý AJAX. Và một file PHP để kiểm tra form nhập.

Trang người dùng

Đây là một trang HTML đơn giản, chỉ có một form nhập liệu, gồm 1 textbox để nhập mã an toàn. Bạn có tạo một file tên captcha_test.htm với nội dung như sau:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>
<head>
<script type="text/javascript" src="ajax_captcha.js"></script>
</head>
<body>
<form id="frmCaptcha" name="frmCaptcha">
<table>
<tr>
<td align="left"><label for="captcha">Captcha</label>
</td>
<td><input id="txtCaptcha" type="text" name="txtCaptcha"
value
="" size="32" />

</td>
<td><img id="imgCaptcha" src="create_image.php" /> </td>
</tr>
<tr>
<td> </td>
<td><input id="btnCaptcha" type="button" value="Captcha Test"
name
="btnCaptcha" onclick="getParam(document.frmCaptcha)" />

</td>
</tr>
</table>
<div id="result"> </div>
</form>
</body>
</html>

Sau khi gõ mã an toàn và bấm nút Captchat Test, thì mã sẽ được kiểm tra bằng ajax và kết quả sẽ chèn vào div có id là result.

Tiếp theo, bạn tạo file php để sinh ra ảnh chứa mã an toàn, và lưu mã an toàn vào session để kiểm tra khi người dùng nhập. Bạn tạo file create_image.php có nội dung như sau:

<?php
//Start the session so we can store what the security code actually is
session_start();
 
//Send a generated image to the browser
create_image();
exit();
 
function create_image()
{
//Let's generate a totally random string using md5
$md5_hash = md5(rand(0,999));
//We don't need a 32 character long string so we trim it down to 5
$security_code = substr($md5_hash, 15, 5);
 
//Set the session to store the security code
$_SESSION["security_code"] = $security_code;
 
//Set the image width and height
$width = 100;
$height = 20;
 
//Create the image resource
$image = ImageCreate($width, $height);
 
//We are making three colors, white, black and gray
$white = ImageColorAllocate($image, 255, 255, 255);
$black = ImageColorAllocate($image, 0, 0, 0);
$grey = ImageColorAllocate($image, 204, 204, 204);
 
//Make the background black
ImageFill($image, 0, 0, $black);
 
//Add randomly generated string in white to the image
ImageString($image, 3, 30, 3, $security_code, $white);
 
//Throw in some lines to make it a little bit harder for any bots to break
ImageRectangle($image,0,0,$width-1,$height-1,$grey);
imageline($image, 0, $height/2, $width, $height/2, $grey);
imageline($image, $width/2, 0, $width/2, $height, $grey);
 
//Tell the browser what kind of file is come in
header("Content-Type: image/jpeg");
 
//Output the newly created image in jpeg format
ImageJpeg($image);
 
//Free up resources
ImageDestroy($image);
}
?>

Nếu bạn xem file create_image.php trên trình duyệt, bạn sẽ thấy mã an toàn sẽ khác nhau mỗi khi bạn refresh trang web. Ở trên chỉ là một đoạn text đơn giản, bạn có thể tự chế bằng cách chọn font chữ, kích thước,độ nghiên... để làm cho CAPTCHA đẹp hơn.

Tiếp theo, bạn tạo một file Javascript có tên ajax_captcha.js để xử lý Ajax, có nội dung như sau:

//Gets the browser specific XmlHttpRequest Object 
function getXmlHttpRequestObject() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest(); //Mozilla, Safari ...
} else if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP"); //IE
} else {
//Display our error message
alert("Your browser doesn't support the XmlHttpRequest object.");
}
}
 
//Our XmlHttpRequest object
var receiveReq = getXmlHttpRequestObject();
 
//Initiate the AJAX request
function makeRequest(url, param) {
//If our readystate is either not started or finished, initiate a new request
if (receiveReq.readyState == 4 || receiveReq.readyState == 0) {
//Set up the connection to captcha_test.html.
//True sets the request to asyncronous(default)

receiveReq.open("POST", url, true);
//Set the function that will be called
//when the XmlHttpRequest objects state changes

receiveReq.onreadystatechange = updatePage;
 
receiveReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
receiveReq.setRequestHeader("Content-length", param.length);
receiveReq.setRequestHeader("Connection", "close");
 
//Make the request
receiveReq.send(param);
}
}
 
//Called every time our XmlHttpRequest objects state changes
function updatePage() {
//Check if our response is ready
if (receiveReq.readyState == 4) {
//Set the content of the DIV element with the response text
document.getElementById('result').innerHTML = receiveReq.responseText;
//Get a reference to CAPTCHA image
img = document.getElementById('imgCaptcha');
//Change the image
img.src = 'create_image.php?' + Math.random();
}
}
 
//Called every time when form is perfomed
function getParam(theForm) {
//Set the URL
var url = 'captcha.php';
//Set up the parameters of our AJAX call
var postStr = theForm.txtCaptcha.name + "=";
postStr += encodeURIComponent( theForm.txtCaptcha.value );
//Call the function that initiate the AJAX request
makeRequest(url, postStr);
}

File javascript này sẽ post mã an toàn lên server bằng đối tượng XMLHttpRequest, rồi nhận kết quả và hiện lên web. File server để kiểm tra mã an toàn được nhập có đúng hay không như sau (bạn lưu lại với tên captcha.php):

<?php
//Continue the session
session_start();
 
//Make sure that the input come from a posted form. Otherwise quit immediately
if ($_SERVER["REQUEST_METHOD"] <> "POST")
die("You can only reach this page by posting from the html form");
 
//Check if the securidy code and the session value are not blank
//and if the input text matches the stored text
if ( ($_REQUEST["txtCaptcha"] == $_SESSION["security_code"]) &&
(!empty($_REQUEST["txtCaptcha"]) && !empty($_SESSION["security_code"])) ) {
echo "<h1>Test successful!</h1>";
} else {
echo "<h1>Test failed! Try again!</h1>";
}
?>

Như vậy là bạn đã tạo xong đoạn kiểm tra mã an toàn, bạn có thể chèn nó vào form của bạn để đảm bảo an toàn. Bạn cũng có thể tăng tính an toàn bằng cách:

  • Xoay các ký tự một cách ngẫu nhiên.
  • Thêm khoảng trắng ngẫu nhiên giữa các ký tự.
  • Sử dùng font TTF và thay đổi font ngẫu nhiên.
  • Thay đổi màu chữ...
Lời bình (0)Add Comment

Viết lời bình

busy