Atualizar o captcha do Yii2 resolve as limitações do widget de captcha padrão, que não possui um botão de atualização e exibe a mesma imagem ao recarregar a página. Este guia técnico explica como implementar um captcha atualizável criando uma classe personalizada CaptchaRefreshable e adicionando lógica de recarregamento automático, melhorando tanto a experiência do usuário (UX) quanto a segurança do formulário.
Por Que Adicionar uma Função de Atualização ao Captcha do Yii2?
O widget de captcha padrão do Yii2 tem duas limitações principais. Primeiro, não fornece um botão ou link para atualizar a imagem do captcha. Segundo, a mesma imagem persiste mesmo ao recarregar a página. Isso pode ser frustrante quando a imagem é difícil de ler. Portanto, implementar uma função para atualizar o captcha do Yii2 é crucial para um processo de verificação mais fluido.
Passo 1: Criar a Classe CaptchaRefreshable
Crie um novo arquivo de classe chamado CaptchaRefreshable.php. Coloque-o no diretório common/models/ para o template Advanced, ou em models/ para o template Basic. Esta classe estenderá a funcionalidade de yii\captcha\Captcha.
<?php
namespace common\models;
class CaptchaRefreshable extends \yii\captcha\Captcha
{
/**
* Sobrescreve o template HTML padrão para adicionar um link de atualização.
*/
public function init()
{
$linkAtualizar = \yii\helpers\Html::a('Nova Imagem', '#', [
'id' => 'refresh-captcha',
'class' => 'text-small'
]);
$this->template = '
<div id="verify-code" class="row">
<div class="col-md-6">{image} ' . $linkAtualizar . '</div>
<div class="col-md-6">{input}</div>
</div>';
parent::init();
}
/**
* Registra o script JavaScript para lidar com a ação de clique no link de atualização.
*/
public function registerClientScript()
{
$view = $this->getView();
$view->registerJs("
$('#refresh-captcha').on('click', function(e){
e.preventDefault();
$('#verify-code img').yiiCaptcha('refresh');
});
");
parent::registerClientScript();
}
}Passo 2: Criar a Classe CaptchaRefreshableAction
Em seguida, crie uma classe de ação personalizada para lidar com a validação do captcha. Esta classe garante que a validação não seja verificada em requisições AJAX, evitando que o código do captcha expire ao clicar no botão de atualização.
<?php
namespace common\models;
use Yii;
class CaptchaRefreshableAction extends \yii\captcha\CaptchaAction
{
public function validate($input, $caseSensitive)
{
// Ignorar validação se a requisição for AJAX.
if (Yii::$app->request->isAjax) {
return true;
}
return parent::validate($input, $caseSensitive);
}
}Passo 3: Integrar o Widget na View de Login
No arquivo de view de login (views/site/login.php), substitua o widget de captcha padrão pelo widget personalizado CaptchaRefreshable.
<?php
use yii\widgets\ActiveForm;
// ... outro código ...
<div class="site-login">
<?php $form = ActiveForm::begin(['id' => 'login-form']); ?>
<?= $form->field($model, 'username') ?>
<?= $form->field($model, 'password')->passwordInput() ?>
<?= $form->field($model, 'verifyCode')->widget(\common\models\CaptchaRefreshable::class) ?>
<?= $form->field($model, 'rememberMe')->checkbox() ?>
<div class="form-group">
<?= Html::submitButton('Login', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>Passo 4: Registrar a Ação no SiteController
Registre a ação CaptchaRefreshableAction no método actions() do SiteController. Isso substitui a configuração de captcha padrão.
<?php
namespace app\controllers;
class SiteController extends Controller
{
// ... outro código ...
public function actions()
{
return [
'error' => [ // ... ],
'captcha' => [
'class' => 'common\models\CaptchaRefreshableAction', // Ação personalizada
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
];
}
}Passo 5: Recarregamento Automático do Captcha ao Atualizar a Página
A implementação acima adiciona um botão de atualização. No entanto, a imagem do captcha não muda ao recarregar a página. Para resolver isso, chame a ação para gerar um novo código no início da ação de login no controlador. Isso garante que a atualização do captcha do Yii2 também ocorra automaticamente.
<?php
public function actionLogin()
{
// Gera um novo código de captcha sempre que a ação de login é acessada.
$this->createAction('captcha')->getVerifyCode(true);
// ... resto do código do processo de login ...
}Seguindo estes cinco passos, você implementou com sucesso uma função completa para atualizar o captcha do Yii2. Esta solução fornece duas melhorias principais: um botão de atualização para os usuários e renovação automática ao recarregar a página. Esta implementação também mantém a compatibilidade com a validação e segurança incorporadas do framework Yii2.

