Menu
Imam Ferianto Blogs
  • Home
  • About
Imam Ferianto Blogs

Mengamankan Form netcore 3.1 dengan Captcha Image buatan sendiri

Posted on June 18, 2020June 18, 2020 by feri

Captcha adalah pengaman form yang bisa berupa rumus matematika, pertanyaan, text, suara, ataupun gambar, ataupun metode lain seperti kuis matching gambar, yang menyakinkan bahwa input dilakukan oleh manusia, bukan robot/bot ataupun otomasi mesin. Ide-nya adalah melindungi form dari otomasi, dengan sesuatu yang secara audio visual dapat diterjemahkan oleh manusia tetapi sulit dimengerti oleh mesin.

Pada sesi kali ini kita akan mencoba membuat captha text dengan menuliskan random text pada Image, harapannya karena ini one time random, maka form akan terproteksi. Seed random text disimpan di server dalam bentuk session yang selanjutkan akan divalidasi pada next process.

Untuk menjalankan captha pada net core 3.0  ini kita perlu menginstall package ImageSharp dengan cara berikut.

dotnet add package SixLabors.ImageSharp --version 1.0.0-rc0002
dotnet add package SixLabors.ImageSharp.Drawing --version 1.0.0-beta0008
dotnet add package SixLabors.Fonts --version 1.0.0-beta0012

Baiklah berikut langsung saja dengan code dan keteranganya (kode telah ditulis ulang dari sample code references).

Data model : CaptchaResult.cs

using System;
using System.Collections.Generic;
using System.IO;

namespace psc.Helper.Captcha
{
	public class CaptchaResult{
                //text dari captha disimpan disini
		public string CaptchaCode { get; set; }

                //byte array dari images
		public byte[] CaptchaByteData { get; set; }
	}

}

 

Captha Utils Generator : Captcha.cs

using System;
using System.Linq;
using System.IO;
using System.Runtime.InteropServices;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Drawing.Processing;
using System.Numerics;

namespace psc.Helper.Captcha
{
    public class Captcha
    {
                //random generator
		private static Random random = new Random();
   
                //random text function
		public static string RandomString(int length)
		{
                  //random character list
      		  const string chars = "ABCDEFGHIJKLMNPRSTUVWXYZ0123456789";
    		  return new string(Enumerable.Repeat(chars, length)
      		  .Select(s => s[random.Next(s.Length)]).ToArray());
		}

                //generator captcha image
    	       public static CaptchaResult GenerateCaptchaImage(int width, int height, int fontsize){
                  //bikin modelnya
    		  CaptchaResult result=new CaptchaResult();

                  //get random string 5 chars saja
    		  result.CaptchaCode=RandomString(5);

                  //buat base image
      		  using (Image img = new Image<Rgba32>(width, height))
                 {
                         //isi backgroundnya putih aja
                        img.Mutate(ctx => ctx.Fill(Color.White));

                        //list random font
    			var fontFamilies = new string[] { "Arial", "Verdana", "Times New Roman" };

                        //list random colors
    			var fontColors = new Argb32[]{
    				new Argb32(0.0f, 0.0f, 1.0f),
    				new Argb32(0.0f, 0.5f, 0.5f),
    				new Argb32(0.5f, 0.0f, 0.5f),
    				new Argb32(0.8f, 0.8f, 0.0f),
    				new Argb32(1.0f, 0.0f, 0.0f),
    				new Argb32(0.8f, 0.0f, 0.8f)
    			};

                        //list random point untuk membuat efek text miring atau rotate
    			var pointx = new float[]{20,15,10};
               
                        //origin  y,x,p  
    	                float y=5;
    	                int x=0;
            	        int p=0;
             
             	        //loop over chars in randomtext
             	        foreach(char c in result.CaptchaCode){
                           //buat path untuk text flow path
       			   PathBuilder pathBuilder = new PathBuilder();
       			   pathBuilder.SetOrigin(new PointF(y, 20));
                	   pathBuilder.AddBezier(new PointF(y, pointx[random.Next(0,pointx.Length)] ), new PointF(y+20, pointx[random.Next(0,pointx.Length)] ), new PointF(y+80, pointx[random.Next(0,pointx.Length)] ), new PointF(y+100, pointx[random.Next(0,pointx.Length)]) );
                	   y+=20;
       		           IPath path = pathBuilder.Build();

                           //pilih random font
                	  var font = SystemFonts.CreateFont(fontFamilies[random.Next(0,fontFamilies.Length)], fontsize, FontStyle.Regular);  
			    
			    	//set textoption to flow path
			    	var textGraphicsOptions = new TextGraphicsOptions() 
                	{
                    	TextOptions = {WrapTextWidth = path.Length}
                	};

                	//create text glyph
                	var glyphs = TextBuilder.GenerateGlyphs(c.ToString(), path, new RendererOptions(font, textGraphicsOptions.TextOptions.DpiX, textGraphicsOptions.TextOptions.DpiY)
                	{
                    	HorizontalAlignment = textGraphicsOptions.TextOptions.HorizontalAlignment,
                    	TabWidth = textGraphicsOptions.TextOptions.TabWidth,
                    	VerticalAlignment = textGraphicsOptions.TextOptions.VerticalAlignment,
                    	WrappingWidth = textGraphicsOptions.TextOptions.WrapTextWidth,
                    	ApplyKerning = textGraphicsOptions.TextOptions.ApplyKerning
                	});

                	//text color
                	var textcolor= fontColors[random.Next(0,fontColors.Length)];
                	img.Mutate(ctx => ctx
                	.Draw(new Argb32(0.9f, 0.9f, 0.9f), 3, path) //draw path
                    .Fill(textcolor, glyphs)); //draw text

            	}

                SixLabors.ImageSharp.Formats.Png.PngEncoder pngEncoder = new SixLabors.ImageSharp.Formats.Png.PngEncoder();
            	pngEncoder.CompressionLevel = 0;
            	using (var ms = new MemoryStream()){
    				img.Save(ms, pngEncoder);
    				result.CaptchaByteData=ms.ToArray();
				}

            }

            return result;

    	}

    }

 }

 

Penerapannya pada Controller Sebagai berikut (HomeController.cs)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using psc.Helper.Captcha;
using psc.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using System.IO;

namespace psc.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }

        public IActionResult Index()
        {
            return View();
        }

        //bagian yang menampilkan form dan captha images
        public IActionResult Contact()
        {
            ViewBag.CaptaSalah=false;
            return View();
        }

        //route yang dipanggil untuk menampilkan gambar
        [Route("get-captcha-image")]
        public IActionResult GetCaptchaImage()
        {
            int width = 200;
            int height = 50;
            int fontsize=45;
          
            CaptchaResult result=Captcha.GenerateCaptchaImage(width, height, fontsize);
      
            HttpContext.Session.SetString("CaptchaCode", result.CaptchaCode);
            
            Stream s = new MemoryStream(result.CaptchaByteData);
            return new FileStreamResult(s, "image/png");
      
        }

        //bagian POST yang di proteksi dengan captha
        [HttpPost]
        public ActionResult Contact([Bind("Inquirytype,Sector,Captcha")] ContactForm model)
        {
            if (ModelState.IsValid)
            {  
                String sistemcaptha=HttpContext.Session.GetString("CaptchaCode");
              
                Console.WriteLine("Inquirytype: "+model.Inquirytype);
                Console.WriteLine("Sector: "+model.Sector);
                Console.WriteLine("Captcha Form: "+model.Captcha);
                Console.WriteLine("Capta: "+ sistemcaptha);

                Console.WriteLine("Capta salah\n\n\n\n");

                ViewBag.CaptaSalah=true;

                return View();
            }  
            else
            {  
  

                return View("Terimakasih");
                

            }  
        }


    }
}

Captcha Result:

 

Sumber :

  • https://medium.com/agile-content-teamwork/captcha-generator-with-sixlabors-libs-on-net-core-3-c0d2600b01d5
  • https://docs.sixlabors.com/

Social Media Links

  • Linkedin Profile
  • Facebook Profile
  • Instagram Profile
  • GitHub Pages
  • Google Play Portofolio
  • Postgresql Training Service
  • PHP Security Training Service
  • Active State Writing

Recent Posts

  • Ngoding Data Analytics di Handphone Part 2
  • Ngoding Data Analytics di Iphone Part 1
  • Cara Mudah Membuat Report Dengan Fastreport pada dotnet core project
  • Cara Alternatif mengakses Webservice Soap pada dotnet core tanpa menggunakan soap client
  • Tutorial Yii2 Singkat padat dan jelas untuk programmer pemula. Bagian 1 – Membuat Aplikasi Penjualan Menggunakan yii2

Archives

  • September 2022
  • May 2021
  • April 2021
  • March 2021
  • January 2021
  • September 2020
  • July 2020
  • June 2020
  • May 2020
  • March 2020
  • February 2020
  • December 2019

Categories

  • #dotnetcore
  • arduino
  • c#
  • data-analytics
  • docker
  • oracle
  • php
  • programming
  • python
  • selingan
  • Uncategorized
©2023 Imam Ferianto Blogs | Powered by WordPress & Superb Themes