[html-formfu] Captcha

Alan Hicks ahicks at p-o.co.uk
Wed Oct 17 21:37:20 GMT 2007


Marcus Ramberg wrote:
> Anyone implemented any form of Captcha support in HTML-FormFu?
> 

Yes, and in testing appears to work well.  As Carl mentions the image is 
rendered as an image block and the form processing checks to see that 
the captch block has been entered correctly.

The captcha sub creates the images and stores the expected text in the 
session for later processing by do_newsletter.  It does mean that 
multiple screens of information are not supported as the captcha session 
info would be overridden, for the feedback forms I'm creating this is 
not considered an issue.

Enjoy,
Alan

sub captcha : Local {
   my ($self, $c) = @_;

   # Create a normal image
   my $your_random_str = 'random-string';
   my $image = GD::SecurityImage->new(
      width     => 300,
      height    => 70,
      lines     => 12,
      thickness => 4,
      ptsize    => 22,
      bgcolor   => '#7cc4c4',
      scramble  => 1,
      font      => '/usr/local/share/fonts/SQR721B.ttf',
      );
   $image->random($your_random_str);
   $image->create('ttf', 'ellipse', '#ffffff', '#b4ddc7');
   $image->particle;
   my($image_data, $mime_type, $random_number) = $image->out;
   $c->session->{captcha_string} = $random_number;
   $c->res->content_type('image/'.$mime_type);
   $c->res->body($image_data)
}

sub do_newsletter : Local : Form() {
   my ($self, $c) = @_;

   if ($c->req->param()) {
     my $form = $c->stash->{form};
     $form->load_config_file('feedback/newsletter.yaml');

     my $captcha = $form->get_constraint({name => 'captcha', type => 
'Range'});
     if ($c->session->{captcha_string}){
       $captcha->min($c->session->{captcha_string});
       $captcha->max($c->session->{captcha_string});
     }else{
       my $param_captcha = $c->req->param('captcha') || 'null';
       $c->log->debug('There is no session captcha_string to match 
'.$param_captcha);
       $captcha->min(5);
       $captcha->max(4);
     }

     $form->process($c->req->params);

     if ($form->submitted_and_valid){
       # Do stuff
     }else{
       $c->response->redirect('newsletter');
     }
   }else{
     $c->response->redirect('newsletter');
   }
}

extract from newsletter.yaml
   - type: Block
     id: captcha_image
     tag: img
     attributes_xml: {src: /feedback/captcha}
   - type: Text
     name: captcha
     label_xml: <b>Security code</b>
     constraints:
       - type: Required
         message: Please enter the text from the image
       - type: Range
         message: Please enter the text from the image



More information about the HTML-FormFu mailing list