Google reCAPTCHA V3 の実装ガイド – C# ASP.NET でのステップ別解説

2024-01-04
Google reCAPTCHA V3
C# ASP.NET 実装
スパム対策
APIキー登録
JavaScriptライブラリ
フォーム処理
セキュリティ
開発ブログ
スパムフィルター
プログラミング

新年あけましておめでとうございます。長らく休眠していた開発ブログを再開するにあたり、今回はGoogle reCAPTCHAの実装についてご紹介します。お問い合わせフォームに多数のスパムが寄せられていたため、Google reCAPTCHAを導入しました。これは自動でスパム判定を行う仕組みで、無料プランでは最大100万件/月まで利用可能です。

C# ASP.NETでの実装方法は以下の通りです。

ステップ 1: APIの登録・キーの取得

 

まず、Google reCAPTCHA管理画面からサイトを登録し、APIキーを取得します。今回はスコアベースのV3を実装します。

登録後、サイトキーとサイトシークレットの二つの値が表示されます。

ステップ2 Viewの作成

JavaScriptライブラリの参照を行います。

 <script src="https://www.google.com/recaptcha/api.js" async defer></script>

次に、以下のようにフォームを設定します。申請ボタンでサイトキーを指定します。

 <form id="form" action="/contactus/thankyou" method="post" class="py-3">
     @Html.AntiForgeryToken()
     <!-- reCAPTCHA widget -->

     <div class="my-2">
         <label>
             *お名前
         </label>
         <input type="text" name="name" required class="form-control" />
     </div>
     <div class="my-2">
         <label>
             *会社名
         </label>
         <input type="text" required name="company" class="form-control" />
     </div>
     <div class="my-2">
         <label>
             *メールアドレス
         </label>
         <input type="email" name="email" required class="form-control" />
     </div>
     <div class="my-2">
         <label>
             *お問合せ内容
         </label>
         <textarea class="form-control" name="text" required rows="10"></textarea>
     </div>

     <div class="py-3 row">
         <div class="col-md-4"></div>
         <div class="col-md-4">
             <button class="btn btn-primary rounded-0 w-100 g-recaptcha"
                     data-sitekey="{ここにサイトキー}"
                     data-callback='onSubmit'
                     data-action='submit'>
                 送信
             </button>
         </div>
     </div>
 </form>

さらに、申請ボタンを押した際にトークンを生成するためのJavaScriptを追加します。

 <script>
     function onSubmit(token) {
         $("#form").submit();
     }
 </script>

ステップ 3 フォームの処理

フォームの処理(サーバーサイド)は以下のように行います。フォーム処理時に受け取ったトークンをGoogle APIに渡し、返ってきた値でフォームの処理を決定します。ここでは戻ってきたスコアの高さを基準にしており、0.5を閾値としています。

  [HttpPost, AutoValidateAntiforgeryToken]
  [Route("/contactus/thankyou")]
  public async Task<IActionResult> ContactUsThankYou(IFormCollection form)
  {
      string name = form["Name"];
      string company = form["Company"];
      string email = form["Email"];
      string text = form["Text"];
      string token = form["g-recaptcha-response"];

      // Initialize HttpClient to make an HTTP request
      var client = _httpClientFactory.CreateClient();
      var RECAPTCHA_SECRET_KEY = "{ここにシークレットキーを指定}";

      var response = await client.PostAsync($"https://www.google.com/recaptcha/api/siteverify?secret={RECAPTCHA_SECRET_KEY}&response={token}", null);
      var responseContent = await response.Content.ReadAsStringAsync();
      var result = Newtonsoft.Json.JsonConvert.DeserializeObject<RecaptchaResponse>(responseContent);

      if (result.Success)
      {
          if (result.score < 0.5)
          {
              ModelState.AddModelError("", "reCAPTCHA validation failed");
              return BadRequest();
          }

          // If validation is successful, proceed with form submission processing
      
          // Prepare the data for the thank-you view
          var view = new HomeContactUsThankYouViewModel()
          {
              Company = company,
              Email = email,
              Name = name,
              Text = text
          };

          // Return the thank-you view
          return View(view);
      }
      else
      {
          // Add error to model state and return the view if validation fails
          ModelState.AddModelError("", "reCAPTCHA validation failed");
          return BadRequest();
      }
  }

  // POCO class to match the structure of the JSON response
  public class RecaptchaResponse
  {
      public bool Success { get; set; }
      // Add other properties as needed, based on the JSON structure
      public string challenge_ts { get; set; }
      public string hostname { get; set; }
      public double score { get; set; }
      public string action { get; set; }
  }

以上の方法で、簡単に導入できる上、スパム対策として非常に有効です。V3はスコア制を採用しており、通常のユーザーに何か特別なアクションを求めることがないため、ユーザー体験を損なわずにスパムをフィルタリングできる点が魅力です。

参照

Google reCAPTCHA 概要

公開日: 2024-01-04