재우니의 블로그

ASP.NET MVC 5 : GOOGLE 구글 리캡챠(reCAPTCHA v3) 활용하기

 

 

구글의 리캡챠(reCAPTCHA v3)  에서 생성한 사이트 키(Site key) 값을 grecaptcha.execute() 에 할당 해 줍니다.

해당 화면을 매번 새로고침 할 때 마다 token 값은 달라집니다.

<script src="https://www.google.com/recaptcha/api.js?render=6LcHpYoUAAAAAITt2G2PEeawHQ8vdvRvUyIf8cKT"></script>
<script>
    grecaptcha.ready(function() {
        grecaptcha.execute('6LcHpYoUAAAAAITt2G2PEeawHQ8vdvRvUyIf8cKT', {action: 'contact_us'}).then(function(token) {
            $("#GoogleCaptchaToken").val(token);
        });
    });
</script>

 

 

 

 

 

전체 컨트롤러 소스 내용

백엔드인 컨트롤러에는 시크릿 키(Secret key) 값을 할당해서 비교하여 맞는지 틀린지 확인을 합니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using ContactFormGoogleReCaptureV3.Models;
using Newtonsoft.Json;

namespace ContactFormGoogleReCaptureV3.Controllers
{
    public class ContactUsController : Controller
    {

        public class CaptchaResponseViewModel
        {
            public bool Success { get; set; }

            [JsonProperty(PropertyName = "error-codes")]
            public IEnumerable<string> ErrorCodes { get; set; }

            [JsonProperty(PropertyName = "challenge_ts")]
            public DateTime ChallengeTime { get; set; }

            public string HostName { get; set; }
            public double Score { get; set; }
            public string Action { get; set; }
        }


        // GET: ContactUs
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public async Task<ActionResult> Index(ContactUsViewModel model)
        {
            if (ModelState.IsValid)
            {
                //token 값을 비밀키와 비교해서 성공여부를 확인한다.
                var isCaptchaValid = await IsCaptchaValid(model.GoogleCaptchaToken);
                if(isCaptchaValid)
                {
                    return RedirectToAction("Success");
                }
                else
                {
                    ModelState.AddModelError("GoogleCaptcha", "The captcha is not valid");
                }

            }

            return View(model);
        }

        private async Task<bool> IsCaptchaValid(string response)
        {
            try
            {
                //비밀키를 넣어주세요!!
                var secret = "6LcHpYoUAAAAAIQTMx-RL3WjsTN9k710FPn-DpOw";
                using (var client = new HttpClient())
                {
                    var values = new Dictionary<string, string>
                    {
                        {"secret", secret},
                        {"response", response},
                        {"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 == "contact_us"
                           && captchaResult.Score > 0.5;
                }
            }
            catch (Exception ex)
            {
                return false;
            }

        }

        public ActionResult Success()
        {
            return View();
        }
    }
}

 

전체 뷰 (view) 내용

 

사이트 키(Site key) 값을 수정해 주세요 😀😀😀😀

@model ContactFormGoogleReCaptureV3.Models.ContactUsViewModel

@{
    ViewBag.Title = "title";
}

<h2>Contact Us</h2>

<script src="https://www.google.com/recaptcha/api.js?render=6LcHpYoUAAAAAITt2G2PEeawHQ8vdvRvUyIf8cKT"></script>
<script>
    grecaptcha.ready(function() {
        grecaptcha.execute('6LcHpYoUAAAAAITt2G2PEeawHQ8vdvRvUyIf8cKT', {action: 'contact_us'}).then(function(token) {
            $("#GoogleCaptchaToken").val(token);
        });
    });
</script>

@using (Html.BeginForm("Index", "ContactUs"))
{
    @Html.ValidationSummary()

    <div class="form-group">
        <label for="Name">Your Name:</label>
        @Html.TextBoxFor(m => m.Name, new { @class="form-control" })
    </div>
    <div class="form-group">
        <label for="Email">Your Email:</label>
        @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
    </div>
    <div class="form-group">
        <label for="Message">Type your message:</label>
        @Html.TextAreaFor(m => m.Message, new { @class = "form-control", rows=5 })
    </div>
    @Html.HiddenFor(m=>m.GoogleCaptchaToken)
    <button type="submit" class="btn btn-default">Submit</button>
}

 

 

참고사이트

 

https://youtu.be/CsqbN-ZrCbc


 

 

구글 리캡챠(reCAPTCHA v3) 등록하기

 

구글 리캡챠(reCAPTCHA v3)를 설정하려면 구글에서 도메인을 등록하여 키값을 발급받은 후 해당 정보를 사용하시면 됩니다.
 
1. 구글 리캡챠(reCAPTCHA v3)에  도메인 등록하기  

 

    1) 구글에 로그인 후 구글 리캡챠(reCAPTCHA v3) 등록 페이지에 정보를 입력합니다.

 

 

    2) 등록에 필요한 정보들을 기입합니다. 도움말 아이콘을 클릭하면 기입할 정보에 대한 안내가 표시됩니다.

      ① Label : 등록할 사이트 식별을 위해 이름을 지정합니다.

      ② reCAPTCHA type : 'reCAPTCHA v3'를 선택합니다.

      ③ Domains
        - 팸 자동생성방지 기능을 적용할 게시판 페이지의 URL을 등록합니다.

        - 메인 도메인 주소를 등록하면 하위 페이지는 자동으로 포함됩니다. 

          예시) shop.com을 등록하면, subdomain.shop.com 페이지를 포함한 4차 도메인까지 자동으로 포함됩니다.

        - 유효한 도메인은 host를 포함하며 path, port, query 및 fragment는 기입하지 않습니다.  

      ④ Owners : 사이트 키(Site key)와 시크릿 키(Secret key)에 대한 소유권이 있으며, 구글 계정만 등록이 가능합니다.

      ⑤ Send alerts to owners : 등록된 도메인에서 문제가 탐지될 시 구글에서 메일을 보냅니다.

    3) 'Submit'을 클릭하면 도메인 등록이 완료되며 사이트 키(Site key)와 시크릿 키(Secret key)가 발급됩니다. 
       두 개의 키는 사용하기 위해 복사해 둡니다.

 

 

 

2. 무료 범위 및 유료 서비스 안내  

    1) 구글 리캡챠(reCAPTCHA v3)는 호출 양을 기준으로 초당 1,000 회 미만 또는 월 1,000,000 회 미만 무료입니다.
    2) 무료 범위 초과 시 구글에서 이메일로 3번의 관련 안내 메일을 보내며 reCAPTCHA Enterprise로 서비스 업그레이드를 선택할 수 있습니다.