Captcha Code not changing

I have the default webapp Comment form w/Captcha. When I send in a comment, then go back to the CommentForm the Verifaction code is the exact same code. What gives?

Yii does not know, when it should invalidate the CAPTCHA image. I’ve worked around this issue with some JS code that reloads the captcha on every GET request (form submissions will use POST in my case):





<div class="captcha">

    <?php $this->widget('CCaptcha',array('captchaAction'=>'user/captcha')) ?>

</div>


<?php

/* simulate a click on "refresh captcha" for GET requests */

if (!Yii::app()->request->isPostRequest)

    Yii::app()->clientScript->registerScript(

        'initCaptcha',

        '$(".captcha a").trigger("click");',

        CClientScript::POS_READY

    );



Thanks Mike, I’ll check this out when I can.

I’m not so bothered by it Captcha not changing on a refresh, but it seems wrong that after you successfully submit a form that Yii doesn’t know that it should change the code. Wouldn’t a open up a mass mailing hack? Admittedly they would all go to the email set in [params], but my emailbox could be flooded with stuff. Just rambling I guess, just think captcha should change atleast on success.

Check CCaptchaAction::testLimit.

Mike is right, please check the following:




         /**

	 * Validates the input to see if it matches the generated code.

	 * @param string $input user input

	 * @param boolean $caseSensitive whether the comparison should be case-sensitive

	 * @return whether the input is valid

	 */

	public function validate($input,$caseSensitive)

	{

		$code = $this->getVerifyCode();

		$valid = $caseSensitive ? ($input === $code) : !strcasecmp($input,$code);

		$session = Yii::app()->session;

		$session->open();

		$name = $this->getSessionKey() . 'count';

		$session[$name] = $session[$name] + 1;

		if($session[$name] > $this->testLimit && $this->testLimit > 0)

			$this->getVerifyCode(true);

		return $valid;

	}



The validation function shows how the widget checks ‘testLimit’ for the number of times the code can be repeated, getVerifyCode has a parameter that if true, it will regenerate the code.

I be dumb :( Where is this code?

My solution was to remove the session key on my controller action on get. Be careful not to remove it in any other place because it will probably fail on server validation.


		$session = Yii::app()->session;

		$prefixLen = strlen(CCaptchaAction::SESSION_VAR_PREFIX);

		foreach($session->keys as $key)

		{

			if(strncmp(CCaptchaAction::SESSION_VAR_PREFIX, $key, $prefixLen) == 0)

				$session->remove($key);

		}



I’ve a suggested patch, please check this

Folks, this works perfectly and I think it’s much safer than the JS one.

I’ve searched for answers for quite a while; and finally, I get a great solution.

The culprit IS the session~ So that’s the best way to eradicate it.

The JS solution would slow down the loading speed, and if the hackers forbid the usage of js in the browser…I just wager that would be rich…

Kudos!

By the way , the codes should be carefully inserted.

In my case, right after

  [u]  if (isset(&#036;_POST['yourForm'])) {[/u]

That’s when the form validation has been accomplished, i.e., when the captcha has been verified.

This is great solution to the yii captcha problem.

I think it should be used after model->save(), in the action.

$testLimit should be set to 2 at least (1 will fail because you have always more than 1 validation when you validate + save). And for ajax, Mike’s solution is good: trigger a refresh on the captcha every time you load the form.

This seems to be more elegant solution to me:


Yii::app()->getController()->createAction('captcha')->getVerifyCode(true);

to force captcha to regenerate on successful validation.

worked well…Thanks