Search code examples
moduleyii2captcha

Captcha field not working on module in Yii2


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'],
    ];
}

Solution

  • 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.