Integrate CakePHP with Kcaptcha

By Andrew Stephanoff aka "stephanoff"
Simple way to integrate CakePHP with Kcaptcha.

KCAPTCHA is a free and open source PHP solution to generate human validation images (CAPTCHA).

KCAPTCHA is meant to be a very strong protected one but requires no special hosting featires, only PHP with GD library.


You can download Kcaptcha from here: http://captcha.ru/en/kcaptcha/. After this, put kcaptcha folder into vendors directory.

Create Captcha component:

Component Class:

Download code <?php 
class CaptchaComponent extends Object
{
    function 
startup(&$controller)
    {
        
$this->controller $controller;
    }

    function 
render()
    {
        
vendor('kcaptcha/kcaptcha');
        
$kcaptcha = new KCAPTCHA();
        
$this->controller->Session->write('captcha'$kcaptcha->getKeyString());
    }
}
?>


Use this component in UsersController:

Controller Class:

Download code <?php 
class UsersController extends AppController
{
    ...
    var 
$components = array('Session''Captcha');
    ...
    function 
captcha()
    {
        
$this->Captcha->render();
    }
    ...
}
?>


Create image tag in view:

View Template:

Download code
    <img src="<?php echo $html->url('/users/captcha'); ?>" />


That's all :)

Comments 216

CakePHP team comments Author comments

Bug

1 Nothing appears

I don't know why i dosn't work with me, i cann't see the image on the page !
Everything is corect but no image :(
help me please
posted Fri, Jan 19th 2007, 05:59 by Firas

Comment

2 There is an error

Hello,

This line have an error:

$this->controller->Session->write('captcha', $kaptcha->getKeyString());

Must be:
$this->controller->Session->write('captcha', $kcaptcha->getKeyString());

Missing 'c' y kcaptcha object ;-)
posted Fri, Jan 19th 2007, 06:33 by Isauro

Comment

3 I notice this

Hello,

This line have an error:

$this->controller->Session->write('captcha', $kaptcha->getKeyString());

Must be:
$this->controller->Session->write('captcha', $kcaptcha->getKeyString());

Missing 'c' y kcaptcha object ;-)

I notice this error and i fixed , and i cann't see the image :(
posted Fri, Jan 19th 2007, 06:42 by Firas

Comment

4 There is an error

After fix problem (comment number 2) - I don't see image too.
But in debug mode 1 - I don't see error.
Error in Kcaptcha?

When I look url: site.com/users/captcha - I see JFIF bla bla may be valid code?) but at the end - I see layout. May be problem here?
posted Wed, Dec 31st 1969, 18:00 by Vladislav

Comment

5 About image not showing

You may not have the image library installed.

Check the kcaptcha docs, see what they require and then check with your host to see if they provide it.

later
posted Wed, Dec 31st 1969, 18:00 by Casey Wilson

Comment

6 About image not showing

I have this library, and function imagecreatejpeg - all this function present...

So. After some fun with placing $this->layout = '';
I get this:

http://surnin.kiev.ua/users/captcha (you see - this image, but wrong header).

So image generating, but not showing - wrong header... Why?

COnstruction
img src=" echo html-> ...." -not work.

Sorry for bad english ;)
posted Wed, Dec 31st 1969, 18:00 by Vladislav

Comment

7 About image not showing

Vladislav
In your response headers, the image is served as Content-Type: text/html
posted Wed, Dec 31st 1969, 18:00 by Spout

Comment

8 About image not showing

Yep. I know.
But why here this header? ;-)

I do all by this manual... Even creating empty captcha.thtml (without this file - not work).

Till this time I cann't find - where put wrong header.
posted Wed, Dec 31st 1969, 18:00 by Vladislav

Question

9 About image not showing

Trouble was in space...

When I past/copy code from this page, I copy also " " in component & controller code... Then I get wrong header.

After removing "?> " in both files I got result.

Sorry for all & thanks! ;-)
posted Wed, Dec 31st 1969, 18:00 by Vladislav

Comment

10 Thanks

Thanks, with this article in about 10 minutes I included the Captcha functionality on my user registration page.

With CakePHP it is really rapid development!
posted Sun, Apr 8th 2007, 12:54 by Michele

Question

11 Not working .. period

I have done everything up till Question(9) above but i can't get it to work.

After 2 nights of suffering and 12 search tabs open in Firefox, i reached the following conclusions:

- KeyString generation works fine and the keystring gets stored in Session.
- The image is generated but the headers are always sent wrong. Even if $layout = "" .. or $layout = null etc.. and even if you exit() after calling $this->Captcha->render().
- Never use IE for debugging .. use Firefox's document source.

I revised my code thoroughly for hidden spaces and missing functions .. everything is clean and still no results.

- Cakephp is not for people with high blood pressure.

- A standalone KCAPTCHA works perfectly. Therefore, all what you need is to use the index.php (that is packeged with KCAPTCHA) directly as the src of your img tag .. and to hell with Cakephp's "Vendor" crap.

now .. my question is .. how can i get Cake to output the image correctly ?

Thanks in advance.

P.S. source code will be available upon request
posted Mon, May 7th 2007, 14:19 by BH

Question

12 generate only a new kcaptcha image

Hi guys,

the situation:

my image tag in the view:
<img class="captchapict" src="<?php echo $html->url('/users/captcha'); ?>" alt="This is a captcha-picture. It is used to prevent mass-access by robots. (see: http://captcha.ru)" name="Captcha">

and a textarea for a message:
<?php echo
$html->textarea('Invitation/personal', array('cols'=>'42', 'rows'=>'4')); ?>

i have a submit button that must generate a new captcha image and the data in the textarea must remain preserved / saved.
<? echo $html->submit('new ID'); ?>

but my problem is that i dont know how to implement this in cakephp. When i press the submit button (new ID) that the image is a new captcha image and the entered data in the textarea is saved!?

the form:
<form action="<?echo $html->url('/users/invite')?>" method="post"> .... </form>

can you help me? thanks!

PS: sorry for my bad english :(

MfG Maidi
posted Wed, May 9th 2007, 13:36 by Maidi

Comment

13 Problem fixed

Comment the echo at the end of app/webroot/index.php.

This echo is used to output performance info but it is corrupting the image file.
posted Mon, Jun 4th 2007, 16:26 by benoit

Comment

14 Be careful integrating this Captcha

In my projects, I often use this Captcha. But last week i had a guestbook applications spammed by Bots, so perhaps this Captcha isnt safe anymore. Anyone else had this problem?
posted Wed, Jul 11th 2007, 10:12 by Tom Diehl

Comment

15 It works

I tried the other captcha available here in bakery, it worked locally but my hosting provider didn't have some Libs so I had to try this one, it worked and I made some changes:
First you need to check you have GD, doing a
<?php echo phpinfo(); ?> will tell you if you have that.
Once I had it working I add a function to validation.php file (like Spout did in http://bakery.cakephp.org/articles/view/captcha-component-with-phpcaptcha) but with some changes

<?php
     
function validateCaptcha($fieldName$params) {
        
$val $this->data[$this->name][$fieldName];
      if(!
defined('captcha'))
           
define('captcha''kcaptcha');
      if (!empty(
$_SESSION['captcha']) && $val == $_SESSION['captcha']) {
            
// clear to prevent re-use
            
unset($_SESSION['captcha']);
            return 
true;
      }
             return 
false
    }
?>

in captcha() function I add this (not really necessary)

   function captcha(){
         if ($this->referer() != "/users/registro"){ /* "/users/registro" is the view I am calling captcha() from */
                 $this->redirect("/");
         }
         else {
             $this->Captcha->render();
        }
   }

My view looks like this

<?php echo $html->hidden("User/foo")?>
<p>Enter the text that appears above</p>
<p>
    <?php echo $html->input('User/captchaText');?>
    <?php echo $error->fieldErrors('User/captchaText'); ?>
</p>

You might wonder what is that hidden field for, someone said (don't remember where, sorry) that idea and I added, sometimes bots fills all fields they find, so we leave this field empty, if the controller checks the field is not empty then we are dealing with a bot.
Finally, in my controller I added this validation rule (so you can see how to do it on your model) as well the hidden field conditional

    if (empty($this->data['User']['foo']))    {
$this->User->validate = array('captchaText' => array('Mycaptcha' => array('method' => 'validateCaptcha', 'message' => 'your error message')));
... 
}


posted Wed, Aug 22nd 2007, 10:06 by Guillermo Mansilla

Question

16 Ajax Request Change The Captcha Image

Hi Guys,

how it is possible to change the captcha image with an ajax request?

thank u very much for your help.

Regards,
Maidi
posted Sat, Oct 6th 2007, 07:15 by Maidi

Question

17 the captcha shows very slow

4s!! so slow, why?
posted Tue, Oct 23rd 2007, 22:04 by xmihu

Comment

18 Not working .. period... Not so sure...

Hi Guys,
I tried KCAPTCHA and I had the same problems as described on post (11). And I did found an answer to this question : "how can i get Cake to output the image correctly ?"

Well, rather than putting the render() method in a component, I created this controller :

Controller Class:

<?php 
class CaptchaController extends AppController {

    var 
$name 'Captcha';
    var 
$uses = array(); 

    function 
index(){
        
vendor('kcaptcha'.DS.'kcaptcha');
        
$kcaptcha = new KCAPTCHA();
        
$this->Session->write('captcha'$kcaptcha->getKeyString());
    }
}
?>


In my login view i have put :

View Template:


...
<?php
echo $form->labelTag('Captcha/usercode''Are you human ?').'<br/>';
echo 
'<img id="captcha" src="'.$html->url('/captcha').'" alt="Captcha" ></img><br/>';
echo 
$html->input('Captcha/captcha').'<br/>';
echo 
'<a href="javascript:void(0);" onclick="javascript:document.images.captcha.src=\''.$html->url('/captcha').'\'">Reload?</a><br/>';
?>
...

The javascript beneath the captcha answers the question of the post (16). "how it is possible to change the captcha image with an ajax request?". Well there's no need for an ajax request to update the captcha.

In the captcha component I have put :

Component Class:

<?php 
class CaptchaComponent extends Object
{
    function 
startup(&$controller){
        
$this->controller $controller;
    }

    function 
validateCaptcha($fieldName$params = array()) {
        
$name $this->controller->name;
        if(isset(
$params['name'])){
            
$name $params['name'];
        }
        
$val $this->controller->data[$name][$fieldName];
        if (!
defined('captcha'))
            
define('captcha''kcaptcha');
        if (!empty (
$_SESSION['captcha']) && $val == $_SESSION['captcha']) {
            
// clear to prevent re-use
            
unset ($_SESSION['captcha']);
            return 
true;
        }
        return 
false;
    }
}
?>

And finally I can put in the login action :
if($this->Captcha->validateCaptcha('captcha',array('name'=>'Captcha'))){
bla bla bla
}
It worked for me, I hope that It'll work for you. I'm using kcaptcha 1.2.5 and cake 1.18.
posted Sat, Dec 1st 2007, 23:54 by Sami Radi

Comment

19 Disable Cache I Hate IE

Friend of mine was testing something in IE and noticed that the image was not regenerated...ever...

Ideally, the kcaptcha code should already do this, but since it doesn't (and I don't like modifying vendor code)...

Just add this to your controller action:
$this->disableCache();
posted Sun, Jan 13th 2008, 11:46 by Baz L

Comment

20 An update for 1.2

“vendors” method has been deprecated a while ago in the *development branch*, but in my case it was failing in silence, (no deprecation warning), so you have to do:

App::import('Vendor', 'kcaptcha/kcaptcha');

instead of:

vendor('kcaptcha/kcaptcha');
posted Wed, Mar 26th 2008, 16:47 by Mariano Guezuraga

Login to Submit a Comment