Integrate CakePHP with Kcaptcha

by 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:

<?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:

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

Create image tag in view:

View Template:


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

That's all :)

Report

More on Components

Advertising

Comments

  • arunsharma posted on 11/17/09 05:23:16 AM
    I had a problem, when the captcha image was not showing on the browser even though the header code was present to send content of type "image/jpeg".

    After spending lot of time on it, i was able to figure out that there was a newline at the end of one of the model file. After removing that newline, the image started showing.

    Hence remove all the extra spaces at the end of model files used by the controller.
  • atomiku posted on 09/17/09 04:14:31 AM
    Some of you may have to allow users to access the captcha action without being logged in.

    Do something along the lines of this, in the user controller:

    function beforeFilter() {
        parent::beforeFilter();
        $this->Auth->allow('some_action', 'forgotpass', 'resetpass' , 'captcha');
    }
  • mguezuraga posted on 03/26/08 04:47:29 PM
    “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');
  • bazil749 posted on 01/13/08 11:46:16 AM
    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();
  • Kainchi posted on 12/01/07 11:54:11 PM
    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.
  • xmihu posted on 10/23/07 10:04:36 PM
    4s!! so slow, why?
  • Maidi posted on 10/06/07 07:15:18 AM
    Hi Guys,

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

    thank u very much for your help.

    Regards,
    Maidi
  • gmansilla posted on 08/22/07 10:06:50 AM
    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')));
    ... 
    }

  • TomDeal posted on 07/11/07 10:12:01 AM
    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?
  • benben posted on 06/04/07 04:26:47 PM
    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.
  • Maidi posted on 05/09/07 01:36:22 PM
    Hi guys,

    the situation:

    my image tag in the view:
    This is a captcha-picture. It is used to prevent mass-access by robots. (see: <a href=http://captcha.ru)" name="Captcha">
    and a textarea for a message:
    $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.
    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:
    ....

    can you help me? thanks!

    PS: sorry for my bad english :(

    MfG Maidi
  • bush posted on 05/07/07 02:19:22 PM
    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
  • sunchaser posted on 04/08/07 12:54:13 PM
    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!
  • isauro posted on 01/19/07 06:33:53 AM
    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 ;-)
    • Phiras posted on 01/19/07 06:42:32 AM
      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 :(
  • Phiras posted on 01/19/07 05:59:32 AM
    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
  • Vladislav posted on 11/30/99 12:00:00 AM
    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?
  • ap0s7le posted on 11/30/99 12:00:00 AM
    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
    • Vladislav posted on 11/30/99 12:00:00 AM
      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 ;)
      • spout posted on 11/30/99 12:00:00 AM
        Vladislav
        In your response headers, the image is served as Content-Type: text/html
        • Vladislav posted on 11/30/99 12:00:00 AM
          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.
  • Vladislav posted on 11/30/99 12:00:00 AM
    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! ;-)
  • daniel.eggelton posted on 11/30/99 12:00:00 AM
    Hi,

    Admittedly, I'm new to cakePHP.

    I really need to implement a captcha system into the guestbook on my website.

    I'm having difficulty integrating the files for kcaptcha into my cake structure.

    Firstly, there are 2 vendors directories:
    1. /cake/vendors/
    2. /cake/app/vendors/

    Which vendors directory am I supossed to have the kcaptcha folder located in?

    Secondly, I'm having difficulty working out exactly where the above snippets of code are meant to go. Not providing an exact filename and/or directory location for the file is not helpful, especially to those of us who understand the fundementals of cakePHP but are still to master it's exact goings on and folder structure.

    So, for the first code snippet ("Create Captcha component:") I created the following file containing the code: /cake/app/controllers/components/captcha_component.php. Is this correct? If not, what should the file be named and where should it be located?

    For the second code snippet ("Use this component in UsersController:") to be honest I had no idea what to do with this. What confuses me is that it refers to UsersController which suggests to me that the code snippet needs to be incorporated into an existing controller named users_controller.php. If this is the case where is this controller because I couldn't locate it anywhere in my cake directories?

    For the third code snippet ("Create image tag in view:") I'm added the code to an existing view file where I want the captcha to appear. Is this correct? Do I need to create any view files specifically for the kcaptcha???

    I'd really appreciate some help. I'm sure it's quite simply to install and get going but please don't put new cakePHP users off using cakePHP and vendors by assuming that anyone using it is already an expert. We all needed to start somewhere afterall and to become an expert at anything you first need to be a novice!

    Thank you.
login to post a comment.