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