Captcha component with Securimage
Securimage is an open-source free PHP CAPTCHA script for generating complex images and CAPTCHA codes to protect forms from spam and abuse. It can be easily added into existing forms on your website to provide protection from spam bots. It can run on most any webserver as long as you have PHP installed, and GD support within PHP. Securimage does everything from generate complicated CAPTCHA images to making sure the code the user entered was correct.
Securimage Features
- Show an image in just 3 lines of code
- Validate submitted entries in less than 6 lines of code
- Customizable code length
- Choose the character set
- TTF font support
- Use custom GD fonts when TTF is not available
- Easily add background images
- Multi colored, angled, and transparent text options
- Arched lines through text
- Generates audible CAPTCHA files in wav format
- Use a word list for creating CAPTCHA codes
Step 1: Download and unzip Securimage archive
Download a Securimage archive (either .zip or .tar.gz) at http://www.phpcaptcha.org/download/ and unzip the archive into the directory /app/vendors/securimage/Step 2: Create captcha component
Filename: /app/controllers/components/captcha.phpComponent Class:
<?php
/**
* Securimage-Driven Captcha Component
* @author debuggeddesigns.com
* @license MIT
* @version 0.1
*/
//cake's version of a require_once() call
vendor('securimage'.DS.'securimage'); //use this with the 1.1 core
//App::import('Vendor','Securimage' ,array('file'=>'securimage'.DS.'securimage.php')); //use this with the 1.2 core
//the local directory of the vendor used to retrieve files
define('CAPTCHA_VENDOR_DIR', APP . 'vendors' . DS . 'securimage/');
class CaptchaComponent extends Object {
var $controller;
//size configuration
var $_image_height = 75; //the height of the captcha image
var $_image_width = 350; //the width of the captcha image
//background configuration
var $_draw_lines = true; //whether to draw horizontal and vertical lines on the image
var $_draw_lines_over_text = false; //whether to draw the lines over the text
var $_draw_angled_lines = true; //whether to draw angled lines on the image
var $_image_bg_color = '#ffffff'; //the background color for the image
var $_line_color = '#cccccc'; //the color of the lines drawn on the image
var $_line_distance = 15; //how far apart to space the lines from eachother in pixels
var $_line_thickness = 2; //how thick to draw the lines in pixels
var $_arc_line_colors = '#999999,#cccccc'; //the colors of arced lines
//text configuration
var $_use_gd_font = false; //whether to use a gd font instead of a ttf font
var $_use_multi_text = true; //whether to use multiple colors for each character
var $_use_transparent_text = true; //whether to make characters appear transparent
var $_use_word_list = false; //whether to use a word list file instead of random code
var $_charset = 'ABCDEFGHKLMNPRSTUVWYZ23456789'; //the character set used in image
var $_code_length = 5; //the length of the code to generate
var $_font_size = 45; //the font size
var $_gd_font_size = 50; //the approxiate size of the font in pixels
var $_text_color = '#000000'; //the color of the text - ignored if $_multi_text_color set
var $_multi_text_color = '#006699,#666666,#333333'; //the colors of the text
var $_text_transparency_percentage = 45; //the percentage of transparency, 0 to 100
var $_text_angle_maximum = 21; //maximum angle of text in degrees
var $_text_angle_minimum = -21; //minimum angle of text in degrees
var $_text_maximum_distance = 70; //maximum distance for spacing between letters in pixels
var $_text_minimum_distance = 68; //minimum distance for spacing between letters in pixels
var $_text_x_start = 10; //the x-position on the image where letter drawing will begin
//filename and/or directory configuration
var $_audio_path = 'audio/'; //the full path to wav files used
var $_gd_font_file = 'gdfonts/bubblebath.gdf'; //the gd font to use
var $_ttf_file = 'elephant.ttf'; //the path to the ttf font file to load
var $_wordlist_file = 'words/words.txt'; //the wordlist to use
function startup( &$controller ) {
//add local directory name to paths
$this->_ttf_file = CAPTCHA_VENDOR_DIR.$this->_ttf_file;
$this->_gd_font_file = CAPTCHA_VENDOR_DIR.$this->_gd_font_file;
$this->_audio_path = CAPTCHA_VENDOR_DIR.$this->_audio_path;
$this->_wordlist_file = CAPTCHA_VENDOR_DIR.$this->_wordlist_file;
//CaptchaComponent instance of controller is replaced by a securimage instance
$controller->captcha =& new securimage();
$controller->captcha->arc_line_colors = $this->_arc_line_colors;
$controller->captcha->audio_path = $this->_audio_path;
$controller->captcha->charset = $this->_charset;
$controller->captcha->code_length = $this->_code_length;
$controller->captcha->draw_angled_lines = $this->_draw_angled_lines;
$controller->captcha->draw_lines = $this->_draw_lines;
$controller->captcha->draw_lines_over_text = $this->_draw_lines_over_text;
$controller->captcha->font_size = $this->_font_size;
$controller->captcha->gd_font_file = $this->_gd_font_file;
$controller->captcha->gd_font_size = $this->_gd_font_size;
$controller->captcha->image_bg_color = $this->_image_bg_color;
$controller->captcha->image_height = $this->_image_height;
$controller->captcha->image_width = $this->_image_width;
$controller->captcha->line_color = $this->_line_color;
$controller->captcha->line_distance = $this->_line_distance;
$controller->captcha->line_thickness = $this->_line_thickness;
$controller->captcha->multi_text_color = $this->_multi_text_color;
$controller->captcha->text_angle_maximum = $this->_text_angle_maximum;
$controller->captcha->text_angle_minimum = $this->_text_angle_minimum;
$controller->captcha->text_color = $this->_text_color;
$controller->captcha->text_maximum_distance = $this->_text_maximum_distance;
$controller->captcha->text_minimum_distance = $this->_text_minimum_distance;
$controller->captcha->text_transparency_percentage = $this->_text_transparency_percentage;
$controller->captcha->text_x_start = $this->_text_x_start;
$controller->captcha->ttf_file = $this->_ttf_file;
$controller->captcha->use_gd_font = $this->_use_gd_font;
$controller->captcha->use_multi_text = $this->_use_multi_text;
$controller->captcha->use_transparent_text = $this->_use_transparent_text;
$controller->captcha->use_word_list = $this->_use_word_list;
$controller->captcha->wordlist_file = $this->_wordlist_file;
$controller->set('captcha',$controller->captcha);
}
}
?>
Step 3: Use the captcha component inside a controller
Filename: /app/controllers/contacts_controller.phpController Class:
<?php
class ContactsController extends AppController {
var $name = 'Contacts';
var $components = array('Captcha');
function securimage($random_number){
$this->autoLayout = false; //a blank layout
//override variables set in the component - look in component for full list
$this->captcha->image_height = 75;
$this->captcha->image_width = 350;
$this->captcha->image_bg_color = '#ffffff';
$this->captcha->line_color = '#cccccc';
$this->captcha->arc_line_colors = '#999999,#cccccc';
$this->captcha->code_length = 5;
$this->captcha->font_size = 45;
$this->captcha->text_color = '#000000';
$this->set('captcha_data', $this->captcha->show()); //dynamically creates an image
}
function index(){
$this->set('captcha_form_url', $this->webroot.'contacts/index'); //url for the form
$this->set('captcha_image_url', $this->webroot.'contacts/securimage/0'); //url for the captcha image
$captcha_success_msg = 'The code you entered matched the captcha';
$captcha_error_msg = 'The code you entered does not match';
if( empty($this->data) ){ //form has not been submitted yet
$this->set('error_captcha', ''); //error message displayed to user
$this->set('success_captcha', ''); //success message displayed to user
$this->render(); //reload page
} else { //form was submitted
if( $this->captcha->check($this->data['Contact']['captcha_code']) == false ) {
//the code was incorrect - display an error message to user
$this->set('error_captcha', $captcha_error_msg); //set error msg
$this->set('success_captcha', ''); //set success msg
$this->render(); //reload page
} else {
//the code was correct - display a success message to user
$this->set('error_captcha', ''); //set error msg
$this->set('success_captcha', $captcha_success_msg); //set success msg
$this->render(); //reload page
//after testing is complete, you would process the other form data here and save it
}
}
}
}
?>
Step 4: Create a Contact model
Filename: /app/models/contact.phpView Template:
<?php
class Contact extends AppModel {
var $useTable = false;
}
?>
Step 5: Create a view to hold the dynamic image
Filename: /app/views/contacts/securimage.thtmlView Template:
<?php echo $captcha_data; ?>
Step 6: Create a view to test the captcha with
Filename: /app/views/contacts/index.thtmlView Template:
<form action="<?php echo $captcha_form_url; ?>" method="post">
<div>Verify :</div>
<div><img src="<?php echo $captcha_image_url; ?>" id="captcha" alt="CAPTCHA Image" /></div>
<div><input type="text" name="data[Contact][captcha_code]" size="10" maxlength="6" value="" /></div>
<div><a href="#" onclick="document.getElementById('captcha').src = '<?php echo $this->webroot;?>contact/securimage/' + Math.random(); return false">Reload Image</a></div>
<div style="color:red;"><?php echo $error_captcha; ?></div>
<div style="color:green;"><?php echo $success_captcha; ?></div>
<div><input type="submit" value="CLICK HERE TEST THE CAPTCHA" /></div>
</form>








http://www.idontplaydarts.com/2011/05/exploit-phpcaptcha-securimage/
http://blog.robotekindo.net/2011/01/captcha-component-with-securimage.html
In my component I am using
$controller->captcha->show("/images/code_bg.gif");
for my own image as a captcha background but it is not working anybody have the solution please help.
Yes and it work !
I am using Captcha component in users controller. I am using isConfigure() function of users controller in homes controller.
function isConfigure() {
if ($this->Auth->user()){
......
return true;
}
else
return false;
}
Its working fine if i use $component=array('Captcha',...) in homes controller. Why we need Captcha components in homes controller? Please help....
Only showing alt, "CAPTCHA Image", and when I check sorce src value is src="/contacts/securimage/0"
I'm using 1.3 and inside of captcha.php
//vendor('securimage'.DS.'securimage'); //use this with the 1.1 core
App::import('Vendor','Securimage' ,array('file'=>'securimage'.DS.'securimage.php')); //use this with the 1.2 core
I'm not sure issue is with 1.3 but I read so many times install steps and comments and nothing can fix my issues. Does anyone try with 1.3?
http://gkrb.ufa-arenda.ru/contacts/securimage/0.453563
i have tried numerous settings but none of them worked. if i run bundled securimage_example.php, it works ok.
class AppController extends Controller {
var $components = array('Session', 'Cookie');
/*
.
.
.
.
*/
?>
class CaptchasController extends AppController {
var $name = 'Captchas';
var $uses = array();
var $components = array('Captcha');
/*
.
.
.
.
*/
?>
Please need some help
Hello,
i have same problem that Nikhil has already stated here. I am trying to put all form errors in one place so they stay at the same level. I have several custom validation functions that i call in model with $validate array but the problem occures when im trying to bring that captcha validation into my model rather than keeping it in controller. since the check() function is the Securimage class i dont feel like moding it. maybe there is way to call for it from my model. or is there any workarounds in general just to keep form and captcha errors together.
Nikhil actually stated the problem i have with putting validation script inside model rather than having it in controller for the sake of keeping error messages together in one place. im validating many things with custom validation functions and i wanted to keep the captcha validation on the same level as those or even lower, which as i can figure can be done by putting the validation function in same place with others. The problem occurs with check() function which is located in Securimage class. I'm not really into moding the securimage classes or files but i can't figure out how could i make the call for that function inside my model.
Any help would be more than welcome.
Thanks
The image “/Path/to/controller/action†cannot be displayed, because it contains errors.
I turned off display_errors and uninstall the plugin for skype, and $_use_gd_font=true. It shows like that too.
Any ideas?
Thanks for the app.zip file providation, it helped me a lot to find out the solution and make Captcha working properly.
Keep up sharing good codes!
Thanks,
Aditya Bhatt
this app configuration uses the latest cake release and has the latest secure image download... hope this helps
(not a native language,sorry.)
there is a difference between "app.zip" and local code,
in vendor/securimage/.
the reason is that the content of zip and tar was different.
(Version 1.0.3.1 http://www.phpcaptcha.org/download/)
thanks.
Thanks for the app.zip ...it's working now...
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at D:\MySiteapp\controllers\components\captcha.php:109) in D:\MySite\app\vendors\securimage\securimage.php on line 422...
If I will comment the session_start() (at securimage.php), it will not display the error but still the image will not display...
By the way, it would be better if you send us a sample working script using the cakephp.. :).. Please help the junins!!! :)
Controller name is mistyped the index view at Reload Image:
webroot;?>contact/securimage/
should be contacts
Thanks,
Andras
Thanks for this useful tutorial. I have used it in my user registration form and it works like charm. However I have one doubt. (Apologies if this question is felt to be slightly off topic)
I use the model to validate the rest of the fields of the registration form i.e by defining an array $ validates. I wanted my captcha to also work through the model (using a function) rather than the controller as described by this example.
I have tried writing one. However I have been unsuccessful. I face errors with "$this->captcha->check($this->data['User']['captcha_code'])"
I am unable to get captcha->check to work in the model... any help with reg to same will be appreciated...
regards
nikhil
What was the problem? Thanks in advance.
I have 2 problem when excute :
first one :
Warning (2): session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at C:\xampp\htdocs\cakephp\app\controllers\contacts_controller.php:53) [APP\vendors\securimage\securimage.php, line 422]
second the image not display
Any idea .... Thank
Do you have any white spaces outside the php tags in your controller class? When I copy the contacts_controller code into my SDK I always have a trailing extra line at the end.
I have added in contacts_controller.php before the line
$this->set('captcha_data', $this->captcha->show()); //dynamically creates an imagethe function
ob_clean();to cleaning output buffer.Now it works perfect. Thanks for the code, it is very useful.
everything works fine but: when i reload the page, the same letters are displayed. I thought everytime the page is reloaded or the user captcha code is false, an another word will be displayed. I have the word list in an Words - Folder, and i runned the server_test file and everything looks ok
Need some help with that.
Thanks
That's a bug in some PHP versions. Yo should replace all the instances to "rand(xxxx,xxxx)" function in the file secureimage.php by "mt_rand(xxxx,xxxx)". This worked for me.
thanks a lot man, this has resolved my problem!
Flowreen
Create /app/models/contact.php:
<?php
class Contact extends AppModel {
var $useTable = false;
}
?>
Once I did this the demo worked perfectly with no other changes.
Anyone have any ideas what I'm doing wrong?
Hello, if you are using the 1.2 version be sure that you change the line in the component:
//App::import('Vendor','Securimage' ,array('file'=>'securimage/securimage.php')); //use this with the 1.2 coreyou have to uncomment that line and comment the other one.Second be sure that you are using all the call to the controller well, if you have your own controller like users change contacts to user.
Third if you have a Auth component you have to add this actions ('index', 'securimage') to the allow. pd: index change for your action.
function beforeFilter(){something like that could be.$this->Auth->allow('signup', 'home', 'update_select', 'confirm', 'index', 'securimage');
}
good luck.
Looks great to.
Well I got it up and running with no problems but I'd like to add the reload button. I cant seem to find the function for it. Any one figured this one out?
Thanks!
justclint
Have you tried using a gd font? ($_use_gd_font var in captcha.php)
Or made sure the code length is > 1? ($_code_length var in captcha.php)
Or made sure the font files exist in the vendors/securimage directory? ($_gd_font_file and $ttf_file vars in captcha.php)
Yes, I probably should have used .ctp - the .thtml extension was used in the cake 1.1 core - old habits.
Hope that helped.
Thanks for the code but I can't get the CAPTCHA image to show any characters. All I see in the image is a couple of arc lines. Any ideas what the problem is?
Also, shouldn't the views in Steps 4-6 have the .CTP extension?
Comments are closed for articles over a year old