Google reCAPTCHA - 在ASP.NET MVC上使用Google reCAPTCHA

限量在前面一篇有簡單介紹到 Google reCAPTCHA,這次這篇要來教大家如何在 ASP.NET MVC 中使用Google reCAPTCH,為什麼要指定用ASP.NET MVC呢?因為限量目前最熟的就MVC,哈哈!廢話不多說馬上進入主題。


其實在 NuGet 中搜尋 Google reCAPTCHA 可以找到很多相關的套件,但因為這次的 reCAPTCHA 是新版,所以很難找到新版的套件,經過肉眼過濾之後,限量終於找到幾套很像新版的 reCAPTCHA套件,一套為 reCaptcha ASP.NET MVC,這套裝好之後裡面幾乎沒有什麼可以用,限量還將 Source Code 載下來看,發現完全沒做好,所以這套二話不說馬上移除;另一套為 reCAPTCHA4net,這套看起來基本上是可以用,但使用上的彈性不大,因為限量想要的一些功能(像驗證成功後再把按鈕顯示出來)在這套中是無法做到的。由於以上原因,限量決定自己來寫一套。

限量使用MVC的 cshtml helper 功能來實作 reCAPTCHA 元件,下面就是 cshtml 的 Code:

ViewFunc.cshtml


@using System.Web.Mvc;

@helper ReCaptchaWidget( System.Web.Mvc.HtmlHelper helper, string submitBtn, string url, string theme = "light" ) 
{
    const string SITE_KEY = "{申請的SITE KEY}";
    <script>
        var onloadCallback = function () {
            grecaptcha.render('reCAPTCHAWidget', {
                'sitekey': '@SITE_KEY',
                'theme': '@theme',
                'callback': function(response) {
                    $.ajax({
                        url: '@url',
                        type: 'POST',
                        dataType: 'json',
                        data: { response: response },
                        success: function (json) {
                            if (json.success) {
                                $('#@submitBtn').show();
                                $('#reCAPTCHAWidget').hide();
                            }
                        }
                    });
                }
            });
        };
    </script>
    <div id="reCAPTCHAWidget"></div>
    <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
}

在這個 ReCaptchaWidget 元件中,onloadCallback 為當按下 reCAPTCHA 驗證按鈕後會去觸發的 javascript function,如果想進行客制化的流程可以在此 function 實作,在這裡限量是將Google reCAPTCHA的驗證字串用Ajax傳到後端進行驗證,如果驗證成功就將Submit按鈕顯示。在這個元件中傳入三個參數,Submit按鈕ID, 驗證reCAPTCHA驗證字串的Url, 樣式(reCAPTCHA有light與dark兩種樣式)。在最下面載入的script中,可以發現因為我們要進行callback動作,所以才會在src的url中加入onload與render的參數,不然沒有加的話就是最基本的reCAPTCHA。


Google reCAPTCH官方文件有提到reCAPTCHA提供三個javascript方法:1. grecaptcha.render:將reCAPTCHA元件Show出來。傳入兩個參數: reCAPTCHA容器的ID與其他參數(SITE KEY, 樣式, callback function...等),下表為render傳入的參數表:



2. grecaptcha.reset:Reset reCAPTCHA 元件。
3. grecaptcha.getResponse:取得reCAPTCHA的驗證字串。

再來我們來看看驗證的Controller端怎麼寫:


[HttpPost]
public string ValidateReCAPTCHA(string response)
{
    var SECRET_KEY = "{申請的SECRET KEY}";
    var client = new WebClient();
    var reply =
        client.DownloadString(
            string.Format( "https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", SECRET_KEY, response ) );
    return reply;
}

這個Action會接收到前端傳來的 reCAPTCHA 驗證字串,然後將在Google申請的SECRET KEY一併傳到Google reCAPTCHA API Server來驗證是否正確,接著會取得一個回傳結果的JSON字串直接回傳回去前端。

Google reCAPTCHA API Server回傳回來的JSON格式有兩個屬性,success與error-codes。success顧名思義為boolean值,true為成功false為失敗;error-codes為錯誤代碼的list,以下為每個error-code代表的含意:

  • missing-input-secret:SECRET KEY遺失(沒傳入)
  • invalid-input-secret:無效的SECRET KEY(錯誤的SECRET KEY)
  • missing-input-response:驗證字串遺失(沒傳入)
  • invalid-input-response:無效的驗證字串(不合格式或SITE KEY錯誤)


再來下面的Code是在cshtml上使用reCaptchaWidget元件:


Note.cshtml


@{
    ViewBag.Title = "Note";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Note</h2>

<div class="container">
    @using ( Html.BeginForm( "Note", "Home", FormMethod.Post, new { @class = "form-grouop" } ) )
    {
        <div class="row">
            <div class="col-xs-6">
                <div class="form-group">
                    <div class="input-group">
                        <div class="input-group-addon">Title</div>
                        @Html.TextBox( "title", string.Empty, new { @class = "form-control" } )
                    </div>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-xs-6">
                <div class="input-group">
                    <div class="input-group-addon">Text</div>
                    @Html.TextBox( "notearea", string.Empty, new { @class = "form-control" } )
                </div>
            </div>
        </div>
        <br/>
        
        //Google reCAPTCHA Widget
        @ViewFunc.ReCaptchaWidget( Html, "btnSubmit", Url.Action( "ValidateReCAPTCHA", "Home" ), "dark" )
        
        <br/>
        <input id="btnSubmit" type="submit" value="Submit" class="btn btn-default" style="display: none" />
    }

</div>

在Html中只需要呼叫ReCaptchaWidget方法並傳入參數就可以自動Gen出reCAPTCHA的Html元件了。

讓我們來看看執行結果:


因為輸入樣式參數為dart,所以reCAPTCHA變成黑色。

驗證成功後reCAPTCHA會消失,取而代之的Submit按鈕出現了。




參考來源:
Venkat Baggu Blog - Google reCAPTCHA in ASP.NET MVC
Google reCAPTCHA論壇 - Asp.Net Mvc Sample code
Google Developers -reCAPTCHA Developer's Guide

留言

  1. 請問一下,若只是在本機端測試,google Register domain 可以打localhost.com嗎?
    因為我只有IDE跟IIS Express

    回覆刪除
  2. 您好,在Google reCAPTCHA官網上有提到:"By default, all keys work on "localhost" (or "127.0.0.1"), so you can always develop and test on your local machine.",也就是你所註冊的Key在localhost是可以work的,但等你的網站掛上網頁伺服器時就要注意是否在你所設定的Domain裡了。

    回覆刪除
  3. 終找到我想做的事 有點厲害 未看先推

    回覆刪除

張貼留言