ASP.Net MVC'de, CAPTCHA ile Güvenlik Kontrolü

Bu yazıda internetin her yerinde karşımıza çıkan güvenlik doğrulaması olan CAPTCHA'nın, MVC ile beraber kullanımının en basit yönetimini göstereceğim. Her şeyden önce, kullanacağım metot fotoğraf + metinden oluşan karmaşık görüntüleme imajlarından değil. Buradaki temel amaç kullanıcıyı bezdirmeden güvenliği sağlamaktır. Bu işlem için kullanılan iki jQuery Javascript'ini makalenin sonundaki linkten indirebilirsiniz.


C# veya MVC'ye görsel güvenlik doğrulaması eklerken kullandığı bu metot dört adımdan oluşmaktadır.

  1. Bir CAPTCHA görseli çizen ve bu görselin cevabını kullanıcının oturum bilgisinde saklayan bir Action oluşturulur.
  2. Model içerisine Captcha değişkeni tanımlanır.
  3. İlgili View kısmına captcha textboxu ve resim alanı eklenir.
  4. Geri dönen veri olşturduğunuz Action'da doğrulanır.
CAPTCHA resminin oluşturlması:

CaptchaController.cs içerisine ekleyin:

        public ActionResult CaptchaImage(string prefix, bool noisy = true)
        {
            var rand = new Random((int)DateTime.Now.Ticks);

            //yeni soru üret
            int a = rand.Next(10, 99);
            int b = rand.Next(0, 9);
            var captcha = string.Format("{0} + {1} = ?", a, b);

            //cevabı sakla
            Session["Captcha" + prefix] = a + b;

            //resim oluştur
            FileContentResult img = null;

            using (var mem = new MemoryStream())
            using (var bmp = new Bitmap(130, 30))
            using (var gfx = Graphics.FromImage((Image)bmp))
            {
                gfx.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                gfx.SmoothingMode = SmoothingMode.AntiAlias;
                gfx.FillRectangle(Brushes.White, new Rectangle(0, 0, bmp.Width, bmp.Height));

                //karmaşa ekle
                if (noisy)
                {
                    int i, r, x, y;
                    var pen = new Pen(Color.Yellow);
                    for (i = 1; i < 10; i++)
                    {
                        pen.Color = Color.FromArgb(
                        (rand.Next(0, 255)),
                        (rand.Next(0, 255)),
                        (rand.Next(0, 255)));

                        r = rand.Next(0, (130 / 3));
                        x = rand.Next(0, 130);
                        y = rand.Next(0, 30);

                        gfx.DrawEllipse(pen, x - r, y - r, r, r);
                    }
                }

                //soruyu ekle
                gfx.DrawString(captcha, new Font("Tahoma", 15), Brushes.Gray, 2, 3);

                //resim olarak çiz
                bmp.Save(mem, System.Drawing.Imaging.ImageFormat.Jpeg);
                img = this.File(mem.GetBuffer(), "image/Jpeg");
            }

            return img;
        }

Birden fazla CAPTCHA kullanmak istiyorsanız depolanan veri değişkenine bir ön ek vererek bunu gerçekleştirebilirsiniz. Ya da da karmaşık bir resim için yazı tiplerini değiştirebilirsiniz.

Metodun model kısmına eklenmesi:

SubscribeModels.cs'nin içerisine ekleyin:

    public class SubscribeModel
    {
        [Required]
        [Display(Name = "Kullanıcı Adı")]
        public string Name { get; set; }

        [Required]
        [DataType(DataType.EmailAddress)]
        [Display(Name = "E-Posta")]
        public string Email { get; set; }

        [Required]
        [Display(Name = "Kaç yapar?")]
        public string Captcha { get; set; }
    }

Metodun view kısmına eklenmesi:

Index.csthml'in içerisine ekleyin:

@model CaptchaMvc.Models.SubscribeModel

@{
    ViewBag.Title = "Captcha Demo";
}

<hgroup class="title">
    <h1>Web Tasarım 101 - </h1>
    <h2>MVC'de görsel doğrulama.</h2>
</hgroup>

<p class="message-info">
    Kullanıcı toplama işleminin sonucunu doğrulama alanına yazmalıdır.
    Resmin üzerine bir kez tıklayınca resim yenilenecektir.
</p>

<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>

@Html.ValidationSummary(false)

@using (Html.BeginForm("Index", "Captcha", FormMethod.Post))
{
    <fieldset>
        <legend>Kayıt Formu</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Email)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Email)
            @Html.ValidationMessageFor(model => model.Email)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Captcha)
            <a href="@Url.Action("Index")">
                <img alt="Captcha" src="@Url.Action("CaptchaImage")" style="" /></a>
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Captcha)
            @Html.ValidationMessageFor(model => model.Captcha)
        </div>

        <p>
            <input type="submit" value="Kayıt Ol" />
        </p>
    </fieldset>
}

Geri dönen oturum verisinin Server tarafından doğrulanması:

CaptchaController.cs'in içerisine ekleyin:

        [HttpPost]
        public ActionResult Index(SubscribeModel model)
        {
            //doğrulamayı çağır
            if (Session["Captcha"] == null || Session["Captcha"].ToString() != model.Captcha)
            {
                ModelState.AddModelError("Captcha", "Toplam değerini yanlış girdiniz.");
                return View(model);
            }

            ModelState.AddModelError("", "Değerler eşleşti.");
            return View();
        }


Yazımı bitirirken şuna değinmek isterim ki yukarıda gördüğünüz kod sadece gösterme amaçlıdır. Eğer ki fazla hit alan ya da saldırıya uğrama ihtimali yüksek bir siteniz var DOS atakları ve benzeri saldırıları engellemek için daha gelişmiş bir kod kullanmanız geremektedir.

Teknoloji için takibe devam edin...

Download linki:


Yorumlar

Bu blogdaki popüler yayınlar

Google Maps Üzerinde Birden Fazla Noktayı İşaretleme

MS SQL Server 2008 - MS SQL Server 2012 Restart Computer Hatası

HTML - Focus Kullanımı