Tutorial Captcha Yii2: Crear Botón de Actualización

Advertisement

Actualizar el captcha de Yii2 soluciona las limitaciones del widget captcha predeterminado, que carece de un botón de actualización y muestra la misma imagen al recargar la página. Esta guía técnica explica cómo implementar un captcha actualizable creando una clase personalizada CaptchaRefreshable y añadiendo lógica de auto-recarga, mejorando tanto la experiencia de usuario (UX) como la seguridad del formulario.

Advertisement

¿Por Qué Añadir una Función de Actualización al Captcha de Yii2?

El widget captcha predeterminado de Yii2 tiene dos limitaciones principales. Primero, no proporciona un botón o enlace para actualizar la imagen del captcha. Segundo, la misma imagen persiste incluso al recargar la página. Esto puede ser frustrante cuando la imagen es difícil de leer. Por lo tanto, implementar una función para actualizar captcha Yii2 es crucial para un proceso de verificación más fluido.

Paso 1: Crear la Clase CaptchaRefreshable

Crea un nuevo archivo de clase llamado CaptchaRefreshable.php. Colócalo en el directorio common/models/ para la plantilla Advanced, o en models/ para la plantilla Basic. Esta clase ampliará la funcionalidad de yii\captcha\Captcha.

Advertisement
<?php
namespace common\models;

class CaptchaRefreshable extends \yii\captcha\Captcha
{
    /**
     * Sobrescribe la plantilla HTML predeterminada para añadir un enlace de actualización.
     */
    public function init()
    {
        $enlaceActualizar = \yii\helpers\Html::a('Nueva Imagen', '#', [
            'id' => 'refresh-captcha',
            'class' => 'text-small'
        ]);

        $this->template = '
            <div id="verify-code" class="row">
                <div class="col-md-6">{image} ' . $enlaceActualizar . '</div>
                <div class="col-md-6">{input}</div>
            </div>';
        parent::init();
    }

    /**
     * Registra el script JavaScript para manejar la acción de clic en el enlace de actualización.
     */
    public function registerClientScript()
    {
        $view = $this->getView();
        $view->registerJs("
            $('#refresh-captcha').on('click', function(e){
                e.preventDefault();
                $('#verify-code img').yiiCaptcha('refresh');
            });
        ");
        parent::registerClientScript();
    }
}

Paso 2: Crear la Clase CaptchaRefreshableAction

A continuación, crea una clase de acción personalizada para manejar la validación del captcha. Esta clase asegura que la validación no se verifique en solicitudes AJAX, evitando que el código captcha caduque al hacer clic en el botón de actualización.

Advertisement
<?php
namespace common\models;

use Yii;

class CaptchaRefreshableAction extends \yii\captcha\CaptchaAction
{
    public function validate($input, $caseSensitive)
    {
        // Omitir validación si la solicitud es AJAX.
        if (Yii::$app->request->isAjax) {
            return true;
        }
        return parent::validate($input, $caseSensitive);
    }
}

Paso 3: Integrar el Widget en la Vista de Login

En el archivo de vista de login (views/site/login.php), reemplaza el widget captcha estándar con el widget personalizado CaptchaRefreshable.

<?php
use yii\widgets\ActiveForm;
// ... otro 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('Iniciar Sesión', ['class' => 'btn btn-primary']) ?>
        </div>

    <?php ActiveForm::end(); ?>
</div>

Paso 4: Registrar la Acción en SiteController

Registra la CaptchaRefreshableAction en el método actions() de SiteController. Esto reemplaza la configuración captcha predeterminada.

<?php
namespace app\controllers;

class SiteController extends Controller
{
    // ... otro código ...

    public function actions()
    {
        return [
            'error' => [ // ... ],
            'captcha' => [
                'class' => 'common\models\CaptchaRefreshableAction', // Acción personalizada
                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
            ],
        ];
    }
}

Paso 5: Auto Actualizar Captcha al Recargar la Página

La implementación anterior añade un botón de actualización. Sin embargo, la imagen del captcha no cambia cuando se recarga la página. Para solucionarlo, llama a la acción para generar un nuevo código al inicio de la acción de login en el controlador. Esto asegura que la actualización del captcha Yii2 también ocurra automáticamente.

<?php
public function actionLogin()
{
    // Genera un nuevo código captcha cada vez que se accede a la acción de login.
    $this->createAction('captcha')->getVerifyCode(true);

    // ... resto del código del proceso de login ...
}

Siguiendo estos cinco pasos, has implementado con éxito una función completa para actualizar captcha Yii2. Esta solución proporciona dos mejoras principales: un botón de actualización para los usuarios y una renovación automática al recargar la página. Esta implementación también mantiene la compatibilidad con la validación y seguridad integradas del framework Yii2.

Artículos Recientes