Sử dụng reCAPTCHA v3 với Livewire

Sử dụng reCAPTCHA v3 với Livewire

Việc sử dụng reCaptcha để hạn chế spam và bot trong các dự án thì đã quá cũ rồi. Nhưng mà việc để sử dụng nó với Livewire thì lại là một câu chuyện khác. Vì nếu bạn hiểu các thức hoạt động của Livewire thì bạn sẽ hiểu nó sẽ hơi không thuộc về nhau.

Mình cũng từng gặp khó khăn trong việc sử dụng reCAPTCHA với Livewire. Trong bài viết này mình sẽ chia sẻ các bạn các mà mình tích hợp nó với Livewire.

Đầu tiên các bạn phải vào Google ReCaptcha để tạo project và lấy key và secret cho dự án của mình. Nhớ nhé trong hướng dẫn này mình sử dụng v3 nên các bạn lưu ý lựa chọn v3 nhé.

Tiếp đến trong .env các bạn thêm cho mình 2 key sau:

RECAPTCHA_KEY=this_is_an_example_site_key
RECAPTCHA_SECRET=this_is_an_example_site_secret
.env

Trong dự án của mình thì mình sẽ thêm config key để tùy chỉnh dự án, do mình còn tích hợp tùy chỉnh config này trong UI và lưu vào database nữa nên các bạn có thể bỏ qua bước này nếu như áp dụng thiết lặp config như mình:

return [
    // ...
    
    'recaptcha' => [
    	'key' => env('RECAPTCHA_KEY'),
        'secret' => env('RECAPTCHA_SECRET'),
    ],
];
/config/services.php

Sau khi hoàn thành bước trên các bạn sẽ thêm script này vào bên dưới view hiển thị của cái form (có thể dùng @stack, @push directive của Laravel Blade để đẩy script vào cuối file layout).

<script src="https://www.google.com/recaptcha/api.js?render={{ config('services.recaptcha.key') }}"></script>

Trong Livewire component các bạn set một biến để lưu lại token, lưu tên gì thì do các bạn hoặc là lưu như mình làm cho tiện gửi request đi:

public $request = [
    // ...
    'recaptcha_token' => null,
];

Trong file blade của component các bạn thêm đoạn x-data này vào thẻ form như sau:

<form wire:submit.prevent x-data="{
    request: @entangle('request').defer,
    async submit() {
        this.request.recaptcha_token = await grecaptcha.execute(
                @js(config('services.recaptcha.key')),
                { action: 'submit' }
         );
         $wire.submit();
    }
}">
    <!-- Form Here -->
</form>

Chỗ $wire.submit(); đây là function submit trong component mà bạn sẽ viết để lưu data.

Các bạn viết function sau để check xem có phải là bot hoặc spam hay không tại component ấy:

public function checkReCaptcha(Request $request)
{
    $response = Http::post(
        'https://www.google.com/recaptcha/api/siteverify?secret=' . config('services.recaptcha.secret') . '&response=' . $request->input('recaptcha_token') . '&remoteip=' . $request->getClientIp()
    );

    if ($response->status() !== 200) {
        return true;
    }

    $result = $response->json();

    if (isset($result['success']) && !! $result['success']) {
        return ($result['score'] ?? 0) >= 0.5;
    }

    return true;
}

Ở trên là cách kiểm tra cơ bản, bạn có thể tách ra làm thành một Validation Rule của Laravel, ở trên mình dùng class Http::class chỉ xuất hiện từ bản Laravel 9, nếu bạn dùng bản thấp hơn bạn có thể dùng thư viện Guzzle hoặc dùng thư viện thuần curl để gửi request qua cho Google ReCaptcha.

API xác minh của Google ReCaptcha sẽ trả về có số điểm tương ứng từ 0 đến 1. Điểm càng cao thì càng uy tín. Ở đây mình để là 0.5 trở lên ở mức trung bình. Còn các bạn có thể thay đổi để phù hợp.

Các bạn có thể tham khảo project của mình để rõ hơn.

Backend của project:

GitHub - vigstudio/vgcomments: Comments package for applications. Using this package, you can create and associate comments with Eloquent models.
Comments package for applications. Using this package, you can create and associate comments with Eloquent models. - GitHub - vigstudio/vgcomments: Comments package for applications. Using this pac...

Frontend bằng Livewire của project:

GitHub - vigstudio/livewire-comments: Livewire comments packages use backend by vgcomments
Livewire comments packages use backend by vgcomments - GitHub - vigstudio/livewire-comments: Livewire comments packages use backend by vgcomments

Các bạn có thể tham khảo. Ở đây mình viết tách riêng FE và BE để tiện dùng cho nhiều mục đích khác nhau nên các bạn xem tham khảo.

Trong Frontend có thể tham khảo ở file:

  • src/Http/Livewire/FormComponent.php
  • resources/views/livewire/form.blade.php
  • resources/views/livewire/comments.blade.php

Trong Backend có thể tham khảo ở file:

  • src/Http/Traits/CommentValidator.php
  • src/Services/CommentService.php

Cảm ơn các bạn đã đọc.