Çarşamba, 21 Ekim 2009

Captcha Kullanımı

 

CAPTCHA internet robotlarına karşı geliştirilen ve kullanıcının insan olup olmadığını ölçen bir sistemdir. Kullanıcının giriş yapması gereken yerlerde bir kelime ya da sayı resim olarak gösterilir, kullanıcının da bu resimdeki kelimeyi forma girmesi ile doğrulama yapılır.

CodeIgniter CAPTCHA sınıfını kendi dağıtım paketi içinde plugin olarak dağıtmaktadır. Hafıza ve veritabanı bağlantılı olarak iki farklı kullanım şekli vardır. Bu yazıda hafızada tutulan şeklinin nasıl kullanıldığını ve dikkat edilmesi gereken önemli noktalarını anlatacağım.

Daha önce anlattığım form uygulamasında hata derleme yazısı formunu captcha kullanarak doğrulama yapalım. Captcha kullanmadan önce dosylarımızın bulunduğu kök dizinine captcha isimli bir dizin açıyor, yazma yetkisi veriyoruz (Linux makineler için 777 modu). Böylece captcha plugini oluşturduğu resimlerini bu dizin altına yazacaktır. Burada önemli nokta olarak htaccess kullanıcılarının, bu dizini .htaccess dosyasında hariç tutmayı (RewriteCond satırına eklemeyi) unutmamak gerektiğidir. Yoksa, formda resim dosyamız görünmez. Örneğimiz için .htaccess dosyası içeriği şöyle olacaktır:

RewriteEngine on
RewriteRule ^$ /index.php [L]
RewriteCond $1 !^(index\.php|captcha|js|video_files|robots\.txt|favicon\.ico)
RewriteRule ^(.*)$ /index.php/$1 [L] 

Yorumların yazılacağı controller dosyamız application/controller dizini altında bulunan yorum.php dosyası olsun. Bu controller dosyasında form() metodunda Captcha için gerekli ayarları yaparak işe başlıyoruz. Captcha plugini çalışmak için bizden minimum olarak üç değişkenin değerini ister: img_path (resim dosyalarının kayıt edildiği dizin. Örneğimizde captcha isimli dizin), img_url (resim dosyalarının bulunduğu dizine erişmek için gerekli web adresi. Örneğimizde http://siteadi.com/captcha) ve font_path (font dosyamızın bulunduğu dizin ve font dosyasının adı. Örneğimizde .././system/fonts/texb.ttf Siz kendi kurulumunuza göre bu ayarı değiştirmelisiniz).

Bu ayarları $vals isimli bir diziye ekliyoruz. Daha sonra create_captcha($vals); fonksiyonunu çağırarak sonucu view dosyalarımızda da kullanacağımız için $data['cap'] isimli değişkene atıyoruz. Bundan sonra eğer kullanıcı tarafından captcha değeri girilmediyse, plugin tarafından oluşturan captcha kelimesi session olarak captcha_word değişkenine atanmalıdır. Böylece ekle() metoduna geçildiğinde captcha değeri doğrulanmış olur. Aksi durumda sürekli yeni captcha değeri session dizinine atandığı için, doğrulama yapılamamaktadır.

<!--?php

class Yorum extends Controller {

 function Yorum()
 {
  parent::Controller();
  $this--->load->library(array('session','error','form_validation'));
 }
 
 function index()
 {
  $this->session->keep_flashdata('msg');
 }

 function form()
 {
  $this->load->plugin('captcha');   

  $vals = array(
     'img_path'  => './captcha/',
     'img_url'  => base_url().'captcha/',
     'font_path'  => '.././system/fonts/texb.ttf'
    );  
    
  $data['cap'] = create_captcha($vals);
  if(!($this->input->post('captcha'))) $this->session->set_userdata('captcha_word',$data['cap']['word']);
  
  $this->load->view('form_view',$data); 

 }
 
 function ekle()
 {
  $this->load->helper('form');  
  
  $this->form_validation->set_rules('email', 'E-posta adresiniz', 'trim|required|valid_email');
  $this->form_validation->set_rules('comment', 'Mesaj', 'trim|required|xss_clean');   
  $this->form_validation->set_rules('captcha', 'CAPTCHA', 'trim|required|xss_clean|callback__verify');   
  
  $this->form_validation->set_message('required', '%s bilgisini girmelisiniz');
  $this->form_validation->set_error_delimiters('

', '

'); if ($this->form_validation->run() == FALSE) { $this->session->set_flashdata('msg', $this->form_validation->_error_array); redirect('yorum/form/'); } else { $create = array( 'email' => $this->input->post('email',TRUE), 'metin' => $this->input->post('comment',TRUE) ); //Burada model dosyanıza $create dizinini göndermelisiniz. $this->session->set_flashdata('msg', 'Yorumunuz siteye eklendi teşekkür ederiz.'); redirect('yorum/form/'); } } function _verify($data) { $captcha = $this->input->post('captcha'); if(strtolower($captcha) != strtolower($this->session->userdata('captcha_word'))) { $this->form_validation->set_message('_verify', 'Girdiğiniz CAPTCHA yanlıştır. Lütfen tekrar deneyiniz.'); return FALSE; } } } /* End of file yorum.php */ /* Location: ./system/application/controllers/yorum.php */

Resimdeki captcha değerinin kullanıcının girdiyle aynı olup olmadığını _verify isimli callback fonksiyonunda kontrol ediyoruz. Kullanıcının girdiği captcha isimli değişkenin değeri, session`da captcha_word ismi ile tutulan değere eşitse kullanıcının insan olduğundan emin oluyoruz.

Formu gösterdiğimiz view dosyamız application/view dizini altındaki form.php dosyasıdır. Form dosyamızın sadeleştirilmiş içeriği aşağıdadır. Burada $cap isimli diziyle gelen resim dosyamızın img kodunu nasıl yazdırdığımıza dikkat etmeliyiz. Dikkat etmemiz gereken bir diğer nokta da $cap[`word´] değişkeninde tutulan capthca değerini hiçbir şekilde form içinden ekle() metoduna aktarmıyor olmamızdır.



  <!--?=$this--->error->error_view()?>

 

Yorum Formu

<form acti>
E-posta adresiniz : <input name="email" size="35" type="text"><br> Mesajınız : <textarea name="comment" cols="35" rows="10" class="textarea"></textarea>
<!--?=$cap['image'];?--> <input name="captcha" size="35" value="" type="text"><br> <input name="add" class="submitbutton" value="GONDER" type="submit">
</form>

CodeIgniter Captcha plugin ile oluşturduğu resim dosyalarınından zamanı geçenleri silerek, tamınladığımız dizinde resimlerin artmasını önler. Captcha`nın geçerli olma süresini yine $val isimli değişkendeki değerleri düzenleyerek değiştirebilirsiniz. Değiştirilmesine izin verilen opsiyonlar şunlardır:

 $vals = array(
     'word'   => 'Random word',//ekrana gelecek kelime
     'img_path'  => './captcha/',//resim yolu
     'img_url'  => 'http://example.com/captcha/',//resim adresi
     'font_path'  => './system/fonts/texb.ttf',//font adresi
     'img_width'  => '150',//resim genişliği
     'img_height' => 30,//resim yüksekliği
     'expiration' => 7200//resmin geçerli olmas süresi-sn.
    );

Bu yazıda anlatılan kodlara buradan ulaşabilir, çalışan örnek uygulamayı test edebilirsiniz.

Yorumlar

Merhaba
post ile gelen form verilerindeki $_POST['key'] key anahtarının ne olduğunu öğrenmem gerekiyor.input class ile sadece value değerini alabiliyoruz fakat benim buradaki key değerini alıp bir fonksiyona parametre olarak aktarmam gerekiyor. $_POST şeklinde kullanım da pek  tabsiye edilmiyor. Nasıl yapabilirim?

@dirilis: Öncelikle sorunuzun yeri bu makale değil. Bu tür sorularınızı Google`daki CodeIgniter grubuna gönderirseniz daha kolay yanıt alırsınız.

Sorunuzun cevabı ise form değişkenlerinin alındığı metoda aşağıdaki kodu yazabilirsiniz:

foreach ($_POST as $key => $value) {    
	$degisken_adi = $key;
        $degeri = $value;
} 

merhaba
bu plugin gayet güzel fakat biraz fazla okunaksız ve büyük/küçük harf, o ve 0, I ve L gibi farkları göz ayıramıyor. tavsiyem verdana gibi bir font kullanmak ve plugin'in 223. satırındaki $pool değişkeninden bazı benzer karakterleri çıkarmak. sonuç daha güzel oluyor.

Merhabalar Fatih hocam, öncelikle bilgilendirici yazınız için teşekkür ederim. Sistemde captcha altında kaydedilen resimleri CI otomatik olarak siliyor mu yoksa onun için ekstra bir ayar mı gerekli?

@Hasan Hüseyin İşler: $val isimli dizinde bulunan expiration indeksli değişken, resimlerin tutulacağı süreyi gösterir. Bu süreyi aşan resimler, form tekrar çalıştırıldığında kontrol edilir ve otomatik silinir.


'expiration' => 7200//resmin geçerli olmas süresi-sn.  

Teşekkür ederim.

Download dosyasına ulaşılamıyor.

@Feriha: Teşekkürler bildirim için. Düzelttim.

Yorum Ekle