Zend Framework – Céges Demo portál – Kapcsolat űrlap – Captcha VIII. rész

Fontos tudnunk, hogy amikor weblapunkra kihelyezünk egy mindenki által látogatható űrlapot, akkor a jó szándékú látogatókon kívül számolnunk kell a rosszakaratúakkal is, valamint a webet böngésző robotokkal akik levél szeméttel látják el az internetes hálózatot. Az ilyen és ehhez hasonló támadások kivédésre az egyik mostanában elterjedt megoldás a Captcha:

Mi is ez a Captcha?

Biztos már mindenki találkozott azzal amikor szeretne regisztrálni, és a regisztrációs űrlapon lát egy képet, alatta mellette egy mezővel, hogy mi szerepel a képen? A képen általában deformált betűk számok jelennek meg, ez azért jó mert a webet böngésző robotok még nem olyan kifinomultak, hogy a képen található betűket számokat ábrákat kiszűrjék s regisztrálni tudjanak.

Most készítsünk mi is egy ilyen képet és tegyük ki az űrlapunk alá. Létrehozunk egy Modelt azaz a korábban létrehozott, MVC modellünkben az application\models\ könyvtárban létrehozunk egy Captcha modelt, így ezt majd több űrlapon is használni tudjuk. A Captcha.php model obejtktumom tartalma a következőképpen néz ki:

<?php
class Captcha
{
public function generatecaptcha()
{
$md5_hash = md5(rand(0,999));
$security_code = substr($md5_hash, 15, 5);
$captchaSession = new Zend_Session_Namespace('captcha');
$captchaSession->captcha = $security_code;
$width = 70;
$height = 30;
$image = ImageCreate($width, $height);
$white = ImageColorAllocate($image, 255, 255, 255);
$black = ImageColorAllocate($image, 0, 0, 0);
$grey = ImageColorAllocate($image, 204, 204, 204);
$mas = ImageColorAllocate($image, 23, 189, 45);
ImageFill($image, 0, 0, $black);
ImageString($image, 10, 10, 10, $security_code, $white);
ImageRectangle($image,0,0,$width-1,$height-1,$grey);
imageline($image, 0, $height/3, $width, $height/4, $grey);
imageline($image, 0, $height/5, $width, $height/2, $grey);
imageline($image, 0, $height/7, $width, $height/1, $grey);
imageline($image, $width/5, 0, $width/3, $height, $mas);
imageline($image, $width/2, 0, $width/6, $height, $mas);
ImageJpeg($image, '../tmp/captcha.jpg');
imagedestroy($image);
}
}
?>

Apróbb változtatásokat eszközöltem sessionba a következőképpen teszem el pl.:

$captchaSession = new Zend_Session_Namespace('captcha');
$captchaSession->captcha = $security_code;

Kép mentése adott helyre adott néven:

ImageJpeg($image, '../tmp/captcha.jpg');

Utasítás segítségével lementem a tmp könyvtáramba captcha.jpg néven 🙂

Majd ezután az $image változót megszüntetem az imagedestroy() utasítás segítségével, a szerver memóriája felszabadul, fontos momentum, ha sokan használják az portálunk ne feledkezzünk meg róla!

Ennek az objektumnak, elengedhetetlen feltétele, hogy a szeverünkön a PHP GD kiterjesztés 1.8-as vagy annál újabb kiterjesztése fusson, különben a futás elakad!

Most már van Captcha képünk a hozzátartozó kódot a munkamenethez illesztettük, most ki kell rajzolni a képet a kapcsolat űrlap meghívása esetén, egy mezőt kell kitenni amibe a felhasználónk a Captcha kódot be tudják írni, majd a feldolgozásnál ezt leellenőrizni.

Az IndexController/kapcsolatAction() eseményét egészítsük ki azzal, hogy a nézetnek (kapcsolat űrlap) számára elkészítünk egy új képet.

Az IndexController.php fájlunk elejére írjuk be a következőt:

require_once 'models/Captcha.php';

Ekkor a Controller számára elérhetővé válik a Captcha.php modelünk.

A kapcsolatAction() sorait egészítsük ki ezzel:

Captcha::generatecaptcha();

Azaz meghívjuk a captcha generáló függvényt, ami elkészíti a tmp könyvtárba az új captcha képet s a kódot a munkamenethez adja.

Ha ez megvan akkor a kapcsolatAction()-höz tartozó kapcsolat.phtml soraiban található űrlapot egészítsük ki a következővel:

<tr><td><?php echo $this->formLabel('captcha','Captcha Kód:');?></td>
<td><img src="../../tmp/captcha.jpg" /></td></tr>
<tr><td><?php echo $this->formLabel('entered_coded','Adja meg a képen látható karaktereket:');?></td>
<td><?php echo $this->formText('entered_coded', $this->escape($this->entered_coded), array('onFocus'=>'this.select();'));?></td></tr>

Két új sor a táblázatban a képpel és a beviteli mezővel:

Zend Framework Captcha - Demó Kft - kapcsolat űrlap

Most le kell kezelnünk a captcha kód helyességét, azaz látogassunk el processKapcsolatAction() eseményre. Szedjük ki az űrlapelemekből a begépelt captcha mező tartalmát így:

$entered_captcha = Zend_Filter::get($this->getRequest()->getPost('entered_coded'), 'StripTags');

Ha ez megvan, az űrlap kitöltését ellenörző if utasítást módosítsuk erre:

if($k_email=='' || $k_targy=='' || $k_uzenet=='' || $entered_captcha==''){

Ekkor leellenőrzödik, hogy minden mező kitöltésre került e. Ha minden rendben van az email küldés előtt ellenőrizzük le a captcha kódot, azaz az felhasználó által begépelt kód megegyezik e a munkamenethez csatolt kóddal. Kiszedjük a munkamenethez csatolt kódot és lementjük captchakod néven:

$captchaSession = new Zend_Session_Namespace('captcha');
if($captchaSession->captcha) {
$captchakod = $captchaSession->captcha;
}

Ha ez megvan nyitunk egy új if utasítást, ahol leellenőrizzük a begépelt és a munkamenetben található kód egyezőségét. Ha nem egyeznek meg, a felhasználónak egy “A captcha kód nem megfelelő!” hibaüzenet jelenik meg és visszadobjuk a kapcsolat oldalra:

if ($entered_captcha != $captchakod) {
$this->_helper->flashMessenger->addMessage("A captcha kód nem megfelelő!");
$this->_redirect('/index/kapcsolat');
}

ha megfelel akkor az if utasítás else ága fut, le azaz az email küldés megtörténik. Lássuk egybe az IndexController/processKapcsolatAction ját:

public function processKapcsolatAction()
{
$entered_captcha = Zend_Filter::get($this->getRequest()->getPost('entered_coded'), 'StripTags');
$k_email = Zend_Filter::get($this->getRequest()->getPost('k_email'), 'StripTags');
$k_targy = Zend_Filter::get($this->getRequest()->getPost('k_targy'), 'StripTags');
$k_uzenet = Zend_Filter::get($this->getRequest()->getPost('k_uzenet'), 'StripTags');
if($k_email=='' || $k_targy=='' || $k_uzenet=='' || $entered_captcha==''){
//ha van olyan mező ami nincs kitöltve akkor "Kérem töltsön ki minden mezőt!"
//felírat jelenjen meg
$this->_helper->flashMessenger->addMessage("Kérem töltsön ki minden mezőt!");
$this->_redirect('index/kapcsolat');
}
else{
//minden mező ki van töltve
$captchaSession = new Zend_Session_Namespace('captcha');
if($captchaSession->captcha) {
$captchakod = $captchaSession->captcha;
}
if ($entered_captcha != $captchakod) {
$this->_helper->flashMessenger->addMessage("A captcha kód nem megfelelő!");
$this->_redirect('/index/kapcsolat');
}
else{
$emailValidator = new Zend_Validate_EmailAddress();
if ($emailValidator->isValid($k_email)) {
//ha valid
$mail = new Zend_Mail();
$mail->setBodyText($k_uzenet);
$mail->setFrom($k_email);
$mail->addTo('info@demokft.hu');
$mail->setSubject($k_targy);
$mail->send();
$this->_helper->flashMessenger->addMessage("Az üzenet sikeresen elküldésre került! Munkatársunk, hamarosan felveszi önnel a kapcsolatot");
$this->_redirect('index/kapcsolat');
}
else{
//minden más esetben
$this->_helper->flashMessenger->addMessage("Az email cím nem felel meg!");
$this->_redirect('index/kapcsolat');
}
}
return true;
}
} // public function processKapcsolatAction()

Ezzel a megoldással, valamilyen szinten sikerült levédenünk kapcsolat oldalunkat a webet böngésző spamrobotok elől.
Minden egyes kapcsolat oldal megtekintésnél, mindig új képet generálunk le,a mit ugyanoda mentünk le captcha.jpeg néven. Webszerver esetén, ne feledkezzünk meg tmp könyvtárunkra írási jogot adjunk, ugyanis ha ezt nem tesszük meg, alkalmazásunk nem tud képet menteni oda. Ennek következménye képpen a kép nem jelenik meg a kapcsolat oldalon, a felhasználónk nem tud mit begépelni s mindig hibaüzenetet kap ez a jobbik eset. Rosszabbik esetben a kapcsolat oldal és így a portálunk sem jelenik meg. Egy szó mint száz figyeljünk, arra hogy tmp könyvtárunkra írási jogunk legyen!

Reklámok

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s