How to Create a Captcha in .Net Core Web API

Step-by-Step Guide
 

Step 1. Install Necessary Packages

You need the following NuGet packages to generate images and manage sessions.

  • System.Drawing: Common for image creation.
  • Microsoft.AspNetCore: A session for session management.

You can install these packages using the .NET CLI.

dotnet add package System.Drawing.Common
dotnet add package Microsoft.AspNetCore.Session

Step 2. Configure Session in Startup.cs

Enable session management by adding the required services and middleware in your Startup. cs.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    // Add session services
    services.AddSession(options =>
    {
        options.IdleTimeout = TimeSpan.FromMinutes(30); // Set session timeout
        options.Cookie.HttpOnly = true; // Make the session cookie HTTP only
        options.Cookie.IsEssential = true; // Make the session cookie essential
    });
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthorization();
    // Use session
    app.UseSession();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Step 3. Create the CAPTCHA Controller

Create a new controller AuthenticateController.cs to handle the CAPTCHA generation and retrieval.

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace CaptchaWebApi.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class AuthenticateController : ControllerBase
    {
        [HttpGet]
        [Route("getCaptcha")]
        public async Task<IActionResult> GetCaptchaAsync()
        {
            string captchaText = GenerateRandomText();
            byte[] captchaImageBytes = GenerateCaptchaImage(captchaText);
            HttpContext.Session.SetString("captcha", captchaText);
            return File(captchaImageBytes, "image/jpeg");
        }
        private string GenerateRandomText(int length = 6)
        {
            Random random = new Random();
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            return new string(Enumerable.Repeat(chars, length)
                .Select(s => s[random.Next(s.Length)]).ToArray());
        }
        private byte[] GenerateCaptchaImage(string text)
        {
            int width = 180;
            int height = 30;
            using (Bitmap bitmap = new Bitmap(width, height))
            {
                using (Graphics graphics = Graphics.FromImage(bitmap))
                {
                    graphics.Clear(Color.AliceBlue);
                    graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
                    using (Font font = new Font("Times New Roman", 16, FontStyle.Bold))
                    {
                        using (Brush brush = new SolidBrush(Color.Black))
                        {
                            SizeF textSize = graphics.MeasureString(text, font);
                            float x = (width - textSize.Width) / 2;
                            float y = (height - textSize.Height) / 2;

                            graphics.DrawString(text, font, brush, x, y);
                        }
                    }
                    using (MemoryStream ms = new MemoryStream())
                    {
                        bitmap.Save(ms, ImageFormat.Jpeg);
                        return ms.ToArray();
                    }
                }
            }
        }
    }
}

Step 4. Validate CAPTCHA

To validate the CAPTCHA, you need an endpoint that compares the user-provided text with the text stored in the session.

Add a method to the CaptchaController for validation.

[HttpPost]
[Route("validateCaptcha")]
public IActionResult ValidateCaptcha([FromBody] string userInputCaptcha)
{
    string storedCaptcha = HttpContext.Session.GetString("captcha");

    if (storedCaptcha != null && storedCaptcha.Equals(userInputCaptcha, StringComparison.OrdinalIgnoreCase))
    {
        return Ok(new { Success = true, Message = "CAPTCHA validation succeeded." });
    }
    else
    {
        return BadRequest(new { Success = false, Message = "CAPTCHA validation failed." });
    }
}

Step 5. Run Api

To Test The Api Run the Api In Swagger And Check the Result the Captcha Image Was Generate In Response With text Now You Can Use The Image In HTML.

Run API

Responses

Conclusion

In this guide, we covered how to create a CAPTCHA in a .NET Core Web API, including generating random text, creating an image, storing the CAPTCHA text in a session, and validating the user input. This approach helps protect your web applications from automated bots by ensuring that only human users can perform certain actions.