BerandaFramework PHPAmankan Login Yii2 dari Brute Force dengan CAPTCHA

Amankan Login Yii2 dari Brute Force dengan CAPTCHA

Serangan brute force untuk menebak password masih menjadi ancaman nyata bagi keamanan website. Tutorial ini memberikan panduan langkah demi langkah untuk mengamankan form login pada framework Yii2 dengan mengaktifkan validasi CAPTCHA secara otomatis setelah beberapa kali percobaan login gagal, sehingga meningkatkan pertahanan layer aplikasi Anda.

Mengapa CAPTCHA Penting untuk Form Login?

Serangan brute force adalah metode lama yang tetap efektif dan sering digunakan peretas. Mereka menggunakan bot untuk mencoba ribuan kombinasi username dan password secara otomatis. Jika form login Anda tidak dilindungi, akun administrator dan data sensitif bisa direbut.

Mengimplementasikan CAPTCHA secara kondisional (hanya muncul saat diperlukan) menjaga user experience tetap baik bagi pengguna sah, sekaligus menjadi tembok bagi bot dan penyerang.

Langkah 1: Modifikasi Model LoginForm.php

Pertama, kita tambahkan properti untuk CAPTCHA dan logika validasinya di model `LoginForm`. Kuncinya adalah membuat CAPTCHA hanya wajib diisi setelah sejumlah percobaan login gagal.

<?php

namespace app\models;

use Yii;
use yii\base\Model;

class LoginForm extends Model
{
    public $username;
    public $password;
    public $rememberMe = true;
    public $verifyCode; // Properti baru untuk CAPTCHA

    // ... kode lainnya ...

    public function rules()
    {
        return [
            // Aturan untuk username dan password
            [['username', 'password'], 'required'],
            ['rememberMe', 'boolean'],
            ['password', 'validatePassword'],

            // ATURAN CAPTCHA: Hanya diperlukan jika loginFailed true
            ['verifyCode', 'required', 'when' => function($model) {
                return $model->loginFailed;
            }, 'message' => 'Kode CAPTCHA wajib diisi setelah beberapa percobaan gagal.'],
            ['verifyCode', 'captcha', 'when' => function($model) {
                return $model->loginFailed;
            }],
        ];
    }

    public function validatePassword($attribute, $params)
    {
        if (!$this->hasErrors()) {
            $user = $this->getUser();
            if (!$user || !$user->validatePassword($this->password)) {
                // INI INTINYA: Hitung jumlah percobaan gagal
                $attempts = Yii::$app->session->get('_loginAttempts', 0) + 1;
                Yii::$app->session->set('_loginAttempts', $attempts);

                $this->addError($attribute, 'Username atau password salah.');
            } else {
                // Reset counter jika login sukses
                Yii::$app->session->remove('_loginAttempts');
            }
        }
    }

    // Getter untuk mengecek status kegagalan
    public function getLoginFailed()
    {
        // CAPTCHA muncul setelah 3 kali gagal
        return Yii::$app->session->get('_loginAttempts', 0) >= 3;
    }

    // ... method getUser() dan lainnya ...
}

Penjelasan Kunci:

  • Properti $verifyCode menampung input CAPTCHA dari user.
  • Fungsi getLoginFailed() memeriksa session _loginAttempts. Jika percobaan gagal ≥ 3, ia mengembalikan true.
  • Parameter 'when' pada aturan validasi membuat aturan untuk verifyCode hanya berlaku jika loginFailed bernilai true.
  • Setiap kali validasi password gagal, counter di session bertambah. Login sukses akan mereset counter.

Langkah 2: Tampilkan CAPTCHA di View Login.php

Selanjutnya, kita modifikasi file view login agar menampilkan widget CAPTCHA hanya ketika kondisi $model->loginFailed terpenuhi.

<?php

use yii\helpers\Html;
use yii\bootstrap5\ActiveForm; // atau yii\widgets\ActiveForm

/* @var $this yii\web\View */
/* @var $form yii\widgets\ActiveForm */
/* @var $model app\models\LoginForm */

$this->title = 'Login';
?>
<div class="site-login">
    <h1><?= Html::encode($this->title) ?></h1>

    <div class="row">
        <div class="col-lg-5">
            <?php $form = ActiveForm::begin(['id' => 'login-form']); ?>

                <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>

                <?= $form->field($model, 'password')->passwordInput() ?>

                <?= $form->field($model, 'rememberMe')->checkbox() ?>

                <!-- BAGIAN CAPTCHA YANG KONDISIONAL -->
                <?php if ($model->loginFailed): ?>
                    <div class="alert alert-warning">
                        Terlalu banyak percobaan login gagal. Harap verifikasi bahwa Anda adalah manusia.
                    </div>
                    <?= $form->field($model, 'verifyCode')->widget(\yii\captcha\Captcha::className()) ?>
                <?php endif; ?>

                <div class="form-group">
                    <?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
                </div>

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

Langkah 3: Konfigurasi Action CAPTCHA di Controller

Widget CAPTCHA memerlukan sebuah action di controller untuk menghasilkan gambar dan memvalidasi kode. Pastikan action ‘captcha’ telah dikonfigurasi di `SiteController`.

<?php

namespace app\controllers;

use yii\web\Controller;

class SiteController extends Controller
{
    // ... actions() lainnya ...

    public function actions()
    {
        return [
            'error' => ['class' => 'yii\web\ErrorAction'],
            // ACTION CAPTCHA WAJIB ADA
            'captcha' => [
                'class' => 'yii\captcha\CaptchaAction',
                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, // Penting untuk environment testing
                'minLength' => 4, // Panjang minimal kode
                'maxLength' => 5, // Panjang maksimal kode
                'offset' => 2, // Tingkat kesulitan visual
                'testLimit' => 1, // Berapa kali kode bisa digunakan (1 = sekali pakai)
            ],
            // ... action lain ...
        ];
    }

    // ... actionLogin() dan method lainnya ...
}

Konfigurasi seperti minLength, maxLength, dan testLimit membantu menyesuaikan tingkat keamanan dan kegunaan CAPTCHA sesuai kebutuhan aplikasi Anda .

Catatan Penting & Keamanan Tambahan

Dengan menerapkan CAPTCHA kondisional ini, Anda telah menambahkan lapisan keamanan penting yang secara cerdas mengganggu alur otomatis serangan brute force, sambil tetap menjaga kemudahan bagi pengguna sah yang hanya sekali salah mengetik password.

Artikel Terbaru