Authen-PluggableCaptcha

 view release on metacpan or  search on metacpan

lib/Authen/PluggableCaptcha/Tutorial.pm  view on Meta::CPAN

then set up a sub / handler to generate the captcha on a url mapping

in this example, the captcha generator is in a central location -- /service/captcha/ -- so we supply the section name as a query arg.  
if the captcha generator were locked into a page, then you could just hardcode the section name
	
	sub render_image {
		my 	( $self )= @_ ;
	
		my 	$sectionName= $self->{'PageUser'}{'ApacheRequest'}->param('section');
	
		#initialize the captcha
		&FindMeOn::Functions::Misc::CAPTCHA_init( $self , $sectionName );
	
		$self->{'PageUser'}{'ApacheRequest'}->content_type('image/jpeg');
		$self->{'__BODY'}= $self->{'CaptchaInstance'}->render( 
			challenge_class=> 'Authen::PluggableCaptcha::Challenge::TypeString', 
			render_class=>'Authen::PluggableCaptcha::Render::Image::Imager' ,  
			font_filename=> '/usr/X11R6/lib/X11/fonts/TTF/VeraMoIt.ttf',
			format=>'jpeg' 
		);
		
		return;
	}


=head2 FAQ

=head3 There is a new constructor for both new and existing CAPTCHAs? I don't quite understand why you do it that way?

There is a single constructer that 'forks' into 2 separate init routines based on an argument to new().

Both arguments create a new KeyManager instance before they fork.

The type='new' routine immediately calls the KeyManager method generate_publickey  ( which could conceivably be a little resource intensive, if you've created a module that hits a db to check for collisions).  The fork was an obvious solution to spli...

The type='existing' routine automatically validates the construction arguments via the KeyManger method validate_publickey, which is unnecessary for new captchas.

Originally there was a single 'new', and from that you could call either 'new()' or 'existing()' -- but more people like 1 line of code.

=head3 Does it really need to know the site secret and seed for an existing CAPTCHA? Intuitively, I would think that it is only needed for a new CAPTCHA, and that only the public keys should be needed for an existing CAPTCHA?

That depends on how the KeyManager class you specify uses the site_secret to validate the key (which is why site_secret is not required in the base class , it can be an empty string ).
A DB backed key does not need the sitesecret for validation.  A logic backed key needs all the construction args to validate.

For example:

  key= md5( $site_secret , $time , $page_name , $session_id ) + ':' + $session
  key= 'xxxxxxxxxxxxxxxxxx:10000001'

If we know the site_secret under that formula, we always have every components of the item at our disposal -- and can validate the key for integrity

The default KeyManager class uses a site_secret to create the key.

=head3 Also, from the example in the Tutorial, it isn't quite clear if you first have to generate a new CAPTCHA, just to get its key, and then use that key to construct an existing CAPTCHA to create the JPEG. This isn't the case, is it? I could call ...

Yes. it renders directly on this example 'Generate a Captcha' above.

I think there is some confusion in this tutorial because i do 2 things that are a little odd:

	a- i run through the captcha generator to pull a new valid key, this way i can use a new example and have a key validate
	b- i run through the captcha validator while i can 'guess' an obviously wrong answer.  The way the system is structured, a solution is only provided when you try to validate the captcha.  That is because you might want to 'Render' an existing sound/...

To display a CAPTCHA, you just create a new object and call the render method , passing in a challenge class and render class.  You can call the render method as often as you'd like.  Currently, the module will transparently validate the key in order...

=head3 You actually need to validate the key before check for a correct answer. But couldn't that data be stored on the backend?

Yes,  You could store the data on the backend.  The 'new' constructor will automatically call a key validator so it behaves more like this:

  my 	$captcha= new()
  if ( !$captcha->EXPIRED && !captcha->INVALID )
  {
  	render
  }
  
=head3 How would I store the key in the backend?

right now, you could either

  $dbh->do( store $captcha_publickey to db );

or

  create a KeyManager subclass, which creates a key and stores it to the db and does the validation

  you might be interested in L<Authen::PluggableCaptcha::KeyManagerDB>, which is a db backed keymanager class


=head3 How would I expire the key in the backend?

Good question.  expire_publickey is a method of the captcha and keymanager classes.  expire it in your page logic, or tell the base class to tell the manager to expire it.  but all that code is up to you.




=head3 Things there I don't grok, and so, it is something I kinda feel should be stored on the backend

That is totally understandable.  A lot of people want DB storage.  This module was written to support that as an option- not a requirement.

=head3 You still need to call new with "new" as type to get a valid key, right? Which means, it isn't completely standalone...

No.

The public key is something that is outwardly facing.

ie 

  http://mysite.com/captcha.jpg?key=abcdefg

you could call

  my $captcha= PluggableCaptcha->new( type="existing" , public_key="abcdefg" );

and then

  render that as an image

or

  process that for an answer




( run in 0.856 second using v1.01-cache-2.11-cpan-39bf76dae61 )