This entire class came out of a chat discussion, and I'm curious on how it looks. (This is like literally 30 minutes of development time.)
The idea is to allow very easy, quick implementations of Google's reCAPTCHA ("I am not a robot") checkbox CAPTCHA algorithm. It only requires minor work from the implementor to make it work properly, and that was the point.
Warning: Minimal implementation effort required.
public class ReCaptchaValidator
{
private const string _HeadScriptInclude = "<script src='https://www.google.com/recaptcha/api.js'></script>";
private const string _ReCaptchaLocationInclude = "<div class=\"g-recaptcha %EXTRACLASSES%\" data-sitekey=\"%SITEKEY%\"></div>";
private readonly string _ReCaptchaSecret;
private readonly string _ReCaptchaSiteKey;
/// <summary>
/// Returns the script to be included in the <code><head></code> of the page.
/// </summary>
public string HeadScriptInclude { get { return _HeadScriptInclude; } }
/// <summary>
/// Use this to get or set any extra classes that should be added to the <code><div></code> that is created by the <see cref="ReCaptchaLocationInclude"/>.
/// </summary>
public List<string> ExtraClasses { get; set; }
/// <summary>
/// Returns the <code><div></code> that should be inserted in the HTML where the reCAPTCHA should go.
/// </summary>
/// <remarks>
/// I'm still not sure if this should be a method or not.
/// </remarks>
public string ReCaptchaLocationInclude { get { return _ReCaptchaLocationInclude.Replace("%SITEKEY%", _ReCaptchaSiteKey).Replace("%EXTRACLASSES%", string.Join(" ", ExtraClasses)); } }
/// <summary>
/// Creates a new instance of the <see cref="ReCaptchaValidator"/>.
/// </summary>
/// <param name="reCaptchaSecret">The reCAPTCHA secret.</param>
/// <param name="reCaptchaSiteKey">The reCAPTCHA site key.</param>
public ReCaptchaValidator(string reCaptchaSecret, string reCaptchaSiteKey)
{
_ReCaptchaSecret = reCaptchaSecret;
_ReCaptchaSiteKey = reCaptchaSiteKey;
}
/// <summary>
/// Determines if the reCAPTCHA response in a <code>NameValueCollection</code> passed validation.
/// </summary>
/// <param name="form">The <code>Request.Form</code> to validate.</param>
/// <returns>A boolean value indicating success.</returns>
public bool Validate(NameValueCollection form)
{
string reCaptchaSecret = _ReCaptchaSecret;
string reCaptchaResponse = form["g-recaptcha-response"];
bool passedReCaptcha = false;
using (WebClient client = new WebClient())
{
byte[] response = client.UploadValues("https://www.google.com/recaptcha/api/siteverify",
new NameValueCollection() { { "secret", reCaptchaSecret }, { "response", reCaptchaResponse } });
string reCaptchaResult = System.Text.Encoding.UTF8.GetString(response);
if (reCaptchaResult.IndexOf("\"success\": true") > 0)
passedReCaptcha = true;
}
return passedReCaptcha;
}
}
Usage:
string reCaptchaSecret = "";
string reCaptchaSiteKey = "";
ReCaptchaValidator rcv = new ReCaptchaValidator(reCaptchaSecret, reCaptchaSiteKey);
bool passedReCaptcha = rcv.Validate(Request.Form);
It should be pretty self-explanatory. You can use the ReCaptchaValidator.HeadScriptInclude
to get the entire <script>
tag for the head, and ReCaptchaValidator.ReCaptchaLocationInclude
to get the <div>
element for placement in the body. These aren't demonstrated here, but are easy to implement.