Sử dụng google recaptcha chống spam website

Về CAPTCHA

CAPTCHA là một công cụ xác thực trên website bằng cách cho người dùng nhập lại dòng chữ trên hình ảnh chứng minh không phải là robot để đảm bảo rằng website của bạn không bị SPAM bằng một công cụ tự động.

Hình ảnh CAPTCHA truyền thống:

Còn về reCAPTCHA

reCAPTCHA là một dịch vụ CAPTCHA miễn phí giúp website của bạn chống lại SPAM, các đăng ký độc hại, hoặc các chương trình tấn công cố gắng che giấu bản thân tạo ra các hành vi giống con người. Nó sử dụng kĩ thuật phân rủi ro để phân biệt giữa con người và robot.

Về google reCAPTCHA

Để sử dụng reCAPTCHA bạn cần đăng kí 1 cặp khóa site_keysecret_key. Về site_key để gọi reCAPTCHA service còn secret_key thì authorizes giữa ứng dụng của bạn và reCAPTCHA server để verify response của user gửi lên.

Hiện tại google đang cung cấp 2 phiên bản reCAPTCHA v3 và v2.

Google reCAPTCHA v3

reCAPTCHA v3 trả về score cho mỗi Request từ ứng dụng của bạn gửi lên (nếu là 1.0 good interaction, thì 0.0 thì a bot). Dựa trên score bạn có thể thực hiện các hành động tiếp theo trong ứng dụng của bạn nhằm tránh sự gián đoạn người dùng(ưu điểm của v3).

Bắt tay làm ví dụ về reCAPTCHA v3

  • Trước tiên bạn phải đăng kí site keysecret key tại đây.

  • sau đó là tạo dùng site_key vừa tạo trên để generate ra 1 token

<form id="submitCaptchaV3" action="index.php" method="post">  
    <input type="hidden" name="token" id="recaptchaResponse">
</form>  
<script src="https://www.google.com/recaptcha/api.js?hl=ja&render=GOOGLE_RECAPTCHA_V3_SITE_KEY"></script>  
<script>  
    let site_key = 'GOOGLE_RECAPTCHA_V3_SITE_KEY';
    grecaptcha.ready(function () {
        grecaptcha.execute(site_key, { action: 'contact' }).then(function (token) {
            $('#recaptchaResponse').val(token);
        });
    });
</script>  
  • Tiếp theo thì sử dụng secret_key tạo ở trên cùng với token tạo ra lúc trước submit lên reCAPTCHA server.
$url = 'https://www.google.com/recaptcha/api/siteverify';
$response = filter_input(INPUT_POST, 'token', FILTER_SANITIZE_STRING);
$data = [
    'secret' => 'GOOGLE_RECAPTCHAR_V3_SECRET_KEY',
    'response' => $response,
];
$options = [
    'http' => [
        'header' => 'Content-type: application/x-www-form-urlencoded\r\n',
        'method' => 'POST',
        'content' => http_build_query($data)
    ]
];

$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$resultJson = json_decode($result);

$resultJson trả về có dạng:

object(stdClass)#2 (5) { ["success"]=> bool(true) ["challenge_ts"]=> string(20) "2020-05-03T04:42:14Z" ["hostname"]=> string(9) "localhost" ["score"]=> float(0.9) ["action"]=> string(7) "contact" }  

dựa vào successscore để xác định là người dùng hay là bot.

Full code có thể xem tại đây.

Một chút về Google reCAPTCHA v2

Với reCAPTCHA v2 thì có thể lựa chọn được loại reCAPTCHA hiển thị với checkbox. Nhưng version này dễ gây ức chế khi cứ phải liên tục check I'm not a robot rồi xác nhận hình ảnh đúng.

Kết hợp reCAPTCHA v3 + v2

Ý tưởng của việc kết hợp này là:

Để tránh làm gián đoạn người dùng khi load page lần đầu tiên ta sẽ sử dụng reCAPTCHA v3 để kiểm tra, dựa trên score(so sánh score với 0.5 - ngưỡng mặc định) để xác định xem là người dùng bình thường hay là bot. 
・ Nếu xác định là người dùng bình thường thì tiếp tục các action tiếp theo.
・ Nếu xác định là bot sẽ load lại page và sử dụng reCAPTCHA v2 show checkbox cho người dùng tích. Sau cùng dựa trên kết đó để tiếp tục action hoặc đưa ra thông báo lỗi.

do hạn chế về mặt thời gian nên mình xin phép đưa ra trong phần tới.

Related article