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:
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:
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:
Frontend bằng Livewire của project:
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.