今更感が半端ないですが、ASP.NET MVC で開発したアプリケーションに reCAPTCHA の version 2 を組み込む方法を調べました。何番煎じか分かりませんが、小ネタ程度にまとめておきます。
reCAPTCHA を使うためには Google のサイトから URL を登録して、トークンを貰う必要があります。
ドキュメントも数ページしかないので、これを読めば誰でも実装は出来るはずです。
Developer's Guide | reCAPTCHA | Google for Developers
流れとしてはビューにタグを追加しておき、POST されたデータを API に投げて正しいかチェックするだけです。この流れは ValidateAntiForgery と似てるので、例によって Action Filter として実装します。
とりあえず作成した ValidateReCaptcha 属性のコードを丸ごと載せておきます。
public class ValidateReCaptchaAttribute : ActionFilterAttribute { private const string SiteVerifyEndpoint = "https://www.google.com/recaptcha/api/siteverify"; private const string ResponseFieldKey = "g-recaptcha-response"; private static readonly string SecretKey = ConfigurationManager.AppSettings["ReCaptcha:SecretKey"]; public override void OnActionExecuting(ActionExecutingContext filterContext) { var data = new NameValueCollection { { "secret", SecretKey }, { "response", filterContext.HttpContext.Request.Form[ResponseFieldKey] }, { "remoteip", filterContext.HttpContext.Request.UserHostAddress } }; var json = new WebClient().UploadValues(SiteVerifyEndpoint, data); var result = JsonConvert.DeserializeObject<ReCaptchaVerifyResponse>(Encoding.UTF8.GetString(json)); if (!result.Success) { throw new ReCaptchaValidationException(result.ErrorCodes[0]); } } } public class ReCaptchaVerifyResponse { public bool Success { get; set; } [JsonProperty("error-codes")] public string[] ErrorCodes { get; set; } }
使い方の説明は要らない気がしますが、検証したいアクションに属性を付けるだけです。
public class HomeController : Controller { public ActionResult Index() { return View(); } [HttpPost] [ValidateReCaptcha] public ActionResult Index(FormCollection collection) { return View("Success"); } }
用意したビューは以下のような感じです。特に言うことはありません。
<script src="https://www.google.com/recaptcha/api.js"></script> <h2>Index</h2> @using (Html.BeginForm()) { <div class="g-recaptcha" data-sitekey="..."></div> <br/> <button type="submit">Submit</button> }
これで準備が出来たので、実際に実行して動作を確認しておきます。ブラウザでページを表示すると、誰もが 1 回は見たことあると思われる CAPTCHA が表示されます。
チェックを入れて Submit を行うと、検証が成功するのでページが表示されます。
チェックを入れずに Submit を行うと、検証に失敗して例外が投げられるので、そこで処理が中断されます。
思ったより簡単な仕組みだったので、昼休みの暇潰し程度で試せました。ASP.NET MVC 6 だと Action Filter が Task ベースになるので、HttpClient を使いたいところです。