0

I have a captcha field in an application form, that correctly works, and one in the login form of the Users module, that does not work.

In the login form I wrote:

<?= $form->field($user, 'captcha')->widget(\yii\captcha\Captcha::className(), [
    'captchaAction' => 'user/captcha',  // Important, otherwise no image shown.
    'template' => '...',
]); ?>

In the User model I wrote:

class User extends ActiveRecord implements IdentityInterface
{
    public $captcha;

    public function rules()
    {
        return [
            ...
            /* Modified after the suggestion of Michal Hynčica. */
            /* I tried also 'users/user/captcha'. */
            ['captcha', 'captcha', 'captchaAction' => 'user/captcha'],
        ];
    }

In the actions() method of the UserController I wrote:

public function actions()
{
    return [
        'captcha' => [
            'class' => 'yii\captcha\CaptchaAction',
        ],
    ];
}

I also added this code in the behaviors() method, although in the other controller, where it works, I didn't write it:

public function behaviors()
{
   return [
        'access' => [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'actions' => ['captcha'],
                    'allow' => true,
                ],
            ],
        ]
   ];
}

Solved. Having some scenarios in the User model, I had to add the "captcha" field to the login scenario:

public function scenarios()
{
    return [
        ...
        self::SCENARIO_LOGIN => ['name', 'password', 'remember', 'captcha'],
    ];
}
anva
  • 5
  • 4

1 Answers1

2

If you are using captcha with different captcha action than default site/captcha you have to set the $captchaAction property in validation rule too. So, in your user model:

class User extends ActiveRecord implements IdentityInterface
{
    public $captcha;

    public function rules()
    {
        return [
            // ...
            ['captcha','captcha', 'captchaAction' => 'users/user/captcha'],
        ];
    }

This is because the yii\captcha\CaptchaAction uses the action's unique ID as key when storing data in session. If the validation rule points to different captcha action it won't be able to validate the code properly.

Michal Hynčica
  • 5,038
  • 1
  • 12
  • 24
  • Thank you, but it is still not working. – anva Mar 27 '23 at 12:21
  • Then you will have to be more specific about your issue or provide [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). Problem description "it's not working" is way too generic. I've tried this solution with the code you've provided in clean yii2 basic app project (with one exception: my user model extended `yii\base\Model` instead of `yii\db\ActiveRecord` and didn't implement IdentityInterface) and it worked fine. – Michal Hynčica Mar 27 '23 at 16:42
  • Well, I modified the code above, inserting the code you suggested in your answer. Regarding your implementation, I think you did it in the application and not in a *module*. As I wrote at the beginning, in my application forms captcha fields work fine, in the Users *module* not. – anva Mar 27 '23 at 19:54
  • I don't know what I could add as further information. I think that is all the needed code to understand the problem. – anva Mar 27 '23 at 20:00
  • Maybe it might help to know, that I also tried to implement recaptacha3, and it also works in the application forms but not in the module ones. – anva Mar 27 '23 at 20:05
  • No, I did it in module. Here is the whole app code https://github.com/hyncica/yii-captcha-in-module-poc, you can check code and test it yourself. – Michal Hynčica Mar 28 '23 at 08:33
  • Ok, thanks, it works indeed, I have to figure out why mine does not. Thanks again. – anva Mar 28 '23 at 18:55
  • @MichalHynčica Always best practice :) Appreciate – Serghei Leonenco Mar 28 '23 at 23:40