【譯】MVC3 20個秘方-(15)使用CAPTCHA去防止惡意軟體自動認可評論(防灌水)

來源:互聯網
上載者:User

問題

有種不太幸運的情況,有人用Bot去提交表單,在整個互連網中造成大量的垃圾。為了防止這種情況的方法之一,是使用一個驗證碼---CAPTCHA:全自動區分電腦和人類的圖靈測試,這迫使使用者把產生的文字輸入到文字框。

(譯者:CAPTCHA是一種更人性化的驗證碼,可以通過視覺和聽覺來區分post的請求是人類還是電腦發出的)

解決方案

NuGet安裝ASP.NET Web Helpers Library  從而在BookCommentsController實現防止而已添加書評的功能。 

討論

需要安裝一個新的類包,使在表單上應用CAPTCHA成為可能。微軟已經建立了一個NuGet web helpers 類包含了CAPTCHA,讓我們很容易實施並且驗證使用者輸入的CAPTCHA。先開啟MVC項目,在vs中選擇Tools→LibraryPackage Manager→Add Library Package Reference。點擊左邊的Online,在第一頁的下方您就可以發現 Asp.net web helpers Library。點擊安裝。

在我們的例子裡。那些自動發送post請求的軟體一般會用在圖書評論上。所以是這裡最完美的添加CAPTCHA的地方。在開始之前你必須在RECAPTCHA website為你的網域名稱註冊。(譯者:一般要用一個gmail賬戶。我們使用自己已有的或者重新註冊一個,在這裡由於我們的項目是在本機練習使用的,我就為我的localhost註冊)。註冊成功之後你可以得到一個公開金鑰(public key)和一個私密金鑰(private key)。

提示:如果你不使用Ajax去包含CAPTCHA,你可以通過以下兩行代碼改變你的view:

@using Microsoft.Web.Helpers;
@ReCaptcha.GetHtml("<你的公開金鑰>", "<你的私密金鑰>")

 

一旦配置完成了,是時候開始更新我們的代碼了。我們需要在BookComments/Index view裡做一些小更改。這個view是前一段建立的,用於使用ajax提交書評。這個Ajax需要更新成:當請求完畢,調用javascript函數去顯示CAPTCHA按鈕。代碼如下:

@model IEnumerable<MvcApplication.Models.BookComment>
@{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
<p>
@Ajax.ActionLink("Create New", "Create", new
{
BookId = ViewBag.BookId
},
new AjaxOptions { UpdateTargetId = "AddComment" })
</p>
<div id="AddComment">
</div>
<script type="text/javascript" src=
"http://www.google.com/recaptcha/api/js/recaptcha_ajax.js">
</script>
<script type="text/javascript">
function DisplayCaptcha() {
Recaptcha.destroy();
Recaptcha.create("6Le27coSAAAAAK8KqpUIGvz3qTDXGa9ud9Xst4yY", "captcha", {});//你的公開金鑰

}
</script>
<table>
<tr>
<th>
Comment
</th>
<th>
Created
</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Comment)
</td>
<td>
@Html.DisplayFor(modelItem => item.Created)
</td>
<td>
@Html.DisplayFor(modelItem => item.Book.Title)
</td>
</tr>
}
</table>

現在,去更新BookComments/create view 。首先添加一個地點去展示CAPTCHA.然後添加一個新的HTML 錯誤訊息,當他們輸入錯誤的驗證碼時,會提示錯誤。最後在ReloadComment  javascript 函數裡更改代碼成不自動reload 書評(僅僅當沒錯的時候才reload)。

@model MvcApplication.Models.BookComment
@{
ViewBag.Title = "Create";
}
<h2>
Create</h2>
@section JavascriptAndCSS {
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"
type="text/javascript"></script>
<script src="
@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"
type="text/javascript"></script>
}
<script type="text/javascript">
function ReloadComments() {
var reload = "@ViewBag.RefreshComments";
if (reload == "False") {
DisplayCaptcha();
} else {
$("#Comments").load("/BookComments/Index?BookId=@ViewBag.BookId");
}
}
</script>
@using (Ajax.BeginForm(new AjaxOptions
{
UpdateTargetId = "AddComment",
OnComplete = "ReloadComments"
}))
{
@Html.Hidden("BookId", (int)ViewBag.BookId);
@Html.ValidationSummary(true)
<fieldset>
<legend>BookComment</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Comment)
</div>
<div class="editor-field">
@Html.TextAreaFor(model => model.Comment)
@Html.ValidationMessageFor(model => model.Comment)
</div>
<div class="editor-label">
Are you human?
</div>
<div class="editor-field">
<div id="captcha">
</div>
@Html.ValidationMessage("Captcha")
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}

最後我們要更新BookCommentsController 去驗證輸入的CAPTCHA。如果驗證不合法,我們就把錯誤訊息添加到ModelState裡去,view把它展示出來。

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication.Models;
using Microsoft.Web.Helpers;
using MvcApplication.Models;
namespace MvcApplication.Controllers
{
public class BookCommentsController : Controller
{
private BookDBContext db = new BookDBContext();
//
// GET: /BookComments/
public ActionResult Index(int BookId)
{
ViewBag.BookId = BookId;
var bookcomments = db.BookComments.Include(
b => b.Book).Where(b => b.BookId == BookId);
return PartialView(bookcomments.ToList());
}
//
// GET: /BookComments/Create
public ActionResult Create(int BookId)
{
ViewBag.BookId = BookId;
ViewBag.RefreshComments = false;
return PartialView();
}
//
// POST: /BookComments/Create
[HttpPost]
public ActionResult Create(BookComment bookcomment)
{
ViewBag.RefreshComments = false;
var captchaSuccess = ReCaptcha.Validate(
"6Le27coSAAAAAM6kZnXU8m1j9");//你的私密金鑰

if (ModelState.IsValid && captchaSuccess)
{
bookcomment.Created = DateTime.Now;
db.BookComments.Add(bookcomment);
db.SaveChanges();
ViewBag.RefreshComments = true;
}
// if captcha failed add error message
if (!captchaSuccess)
{
ModelState.AddModelError("Captcha",
"Invalid CAPTCHA");
}
ViewBag.BookId = bookcomment.BookId;
return PartialView(bookcomment);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}

(譯者:是我實踐之後的,不知道這個CAPTCHA的背景樣式是否能自訂,如果可以的話就太酷了!)

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.