CoP Prince of Songkla University Phuket Campus's Blog

การใช้ Google reCAPTCHA Version 3 ร่วมกับ ASP.NET

3 February 2020 | NONTAPON RATTANAPITTAYAPORN | 1 Comment

เนื่องด้วยในชิ้นงานที่กำลังพัฒนามีหน้าแบบฟอร์มที่อนุญาตให้บุคคลทั่วไปสามารถกรอกข้อมูลเข้าสู่ระบบได้ เพื่อป้องกันหรือลดปัญหาจากโปรแกรมอัตโนมัต หรือ บอท (Bot) มารบกวนการทำงานของระบบจึงจำเป็นต้องนำโปรแกรมประเภท CAPTCHA (แคปช่า) มาช่วยในการคัดกรอง

รูปแบบการทำงานของ CAPTCHA มีหลายหลายแบบ เช่น การกรอกข้อความตามภาพที่แสดง การตอบคำถามต่างๆ หรือ การเลือกชุดภาพจากคำถาม

สำหรับ reCAPTCHA เป็นหนึ่งใน บริการ ของ Google ปัจจุบันมีออกมาแล้ว 3 เวอร์ชั่น โดยเวอร์ชั่น 1 ผู้ใช้ต้องดูภาพตัวอักษณบิดๆ เบี้ยวๆ และกรองข้อความให้ถูกต้อง เวอร์ชั่น 2 มักใช้วิธีให้ ผู้ใช้ต้องคลิก [ / ] I’m not a robot และในเวอร์ชั่น 3 จะมีการนำระบบวิเคราะห์ความเสี่ยงมาใช้ในการประเมิน ไม่รบกวนการทำงานของผู้ใช้ และส่งผลคะแนนกลับมา โดย 1.0 เป็นการสื่อสารที่ปลอดภัย ในขณะที่ 0.0 มีความเป็นไปได้สูงที่จะเป็นบอท ผู้ดูแลเว็บไซต์สามารถกำหนดค่าความเสี่ยงและพิจารณษดำเนินการต่อได้เอง

ลำดับแรกของการใช้ Google reCAPTCHA V3 นั้น ผู้ดูแลเว็บไซต์ต้องเข้าไปกำหนดค่าการใช้งานที่ https://www.google.com/recaptcha/admin โดยเลือกใช้แบบเวอร์ชั่น 3 กำหนดค่าโดเมน เป็น localhost และชื่อที่ได้แจ้งจดโดเมนไว้จริงๆ ยอมรับข้อกำหนดการใช้งาน หลังจากบันทึกจะ คีย์สำหรับเว็บไซต์ (public) และ คีย์ลับ (secret) สำหรับนำไปใช้งาน

ภาพด้านล่างนี้แสดงลำดับการทำงานเมื่อผู้ใช้ หรือ Client ส่ง Request มายัง Web Server โดย Controller ใน Framework ของ ASP.NE MVC จะรับ Request และส่งหน้าจอ หรือ View กลับไปยัง Client โดยใน View จะมีการเรียกใช้บริการ Google reChaptchaV3 ที่แนบ public_key ของเราไปด้วย เมื่อโหลด api.js สำเร็จ สคริปต์จะทำงานอีกครั้ง และได้ response-token กลับมา

<input type="hidden" id="captcha" name="captchaToken"/>

<script src="https://www.google.com/recaptcha/api.js?render={Your public key}"></script>
<script>
    grecaptcha.ready(function() {
        grecaptcha.execute('{Your public key}', { action: '{your action name}' }).then(function (token) {
            $("#captcha").val(token);
    });
});
</script>

หลังจากผู้ใช้ได้กรอกข้อมูลต่างๆ ครบถ้วน และกด Submit ข้อมูล เว็บไซต์จะทำการ POST ค่า และ response-token กลับไปยัง Web Server  และเรียกใช้ reCaptchaV3 API ผู้พัฒนารับผลคะแนนมาพิจารณาและดำเนินการอื่นๆ ต่อไป

            try
            {
                var secret = "{Your secret key}";
                using (var client = new HttpClient())
                {
                    var values = new Dictionary<string, string>
                    {
                        {"secret", secret},
                        {"response", captchaToken},
                        {"remoteip", Request.UserHostAddress},
                    };
                    var content = new FormUrlEncodedContent(values);
                    var verify = await client.PostAsync("https://www.google.com/recaptcha/api/siteverify", content);
                    var captchaResponseJson = await verify.Content.ReadAsStringAsync();
                    var captchaResult = JsonConvert.DeserializeObject<CaptchaResponseViewModel>(captchaResponseJson);
                    return captchaResult.Success && captchaResult.Action == "selfenroll" && captchaResult.Score > 0.5;
                }
            }
            catch (Exception)
            {
                return false;
            }
            return true;

สำหรับรายละเอียดเพิ่มเติมสามารถศึกษาต่อได้ที่
https://www.google.com/recaptcha/intro/v3.html
https://developers.google.com/recaptcha/docs/v3

1 thought on “การใช้ Google reCAPTCHA Version 3 ร่วมกับ ASP.NET”

  1. NONTAPON RATTANAPITTAYAPORN NONTAPON RATTANAPITTAYAPORN says:

    สำหรับ หน้าฟอร์มที่ช่องให้กรอกมาก หรือ การที่หน้าจอทิ้งว่างไป อาจทำให้ response token หมดอายุก่อนเกิดการ submit ข้อมูล นั่นเป็นปัญหาที่ token มีอายุน้อยเกินไป เพียง 2 นาที

    https://stackoverflow.com/questions/54437745/recaptcha-v3-how-to-deal-with-expired-token-after-idle

    Haradzieniec : “The token must be generated later than on page load. It should be generated right before we send it to backend. With another words, we click on the button (from my example), then get the generated token, then send the token to backend.

    This solution makes sense and fixes my issue”

Leave a Reply