【译】MVC3 20个秘方-(15)使用CAPTCHA去防止恶意软件自动提交

来源:未知 责任编辑:智问网络 发表时间:2013-09-22 21:34 点击:

 

问题

有种不太幸运的情况,有人用自动程序去提交表单,在整个互联网中造成大量的垃圾。为了防止这种情况的方法之一,是使用一个验证码---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的背景样式是否能自定义,如果可以的话就太酷了!)

\

 

作者 技术弟弟

    发表评论
    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
    用户名: 验证码:点击我更换图片
    最新评论 更多>>

    推荐热点

    • 浅析.NET下XML数据访问新机制
    • asp.net 面试+笔试题目第1/2页
    • C# 邮件地址是否合法的验证
    • asp.net 设置GridView的选中行的实现代码
    • C#高级编程:数据库连接[1]
    • 经典C++程序1
    • IIS 自动回收导致后台定时器失效的问题解决
    • ASP.NET&#160;GridView列表代码示例
    • Asp.net MVC源码分析--Action Filter的链式调用
    网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
    Copyright © 2008-2015 计算机技术学习交流网. 版权所有

    豫ICP备11007008号-1