Skip to content

ManualMaster/Edi.Captcha.AspNetCore

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ManualMaster specific info

This is the fork of Edi.Captcha library which we use for rendering the captcha control in web forms.

However, the functionality we added has been merged into the main library: EdiWang#8

Consequently, Edi.Captcha library starting from version 3.11 should support our functionalities, so the official Nuget package can be used again. We can remove this repository at all as soon as we use Edi.Captcha version 3.11+ and it doesn't cause any issues.

Edi.Captcha.AspNetCore

The Captcha module used in my blog

.NET Core

NuGet

Usage

0. Install from NuGet

NuGet Package Manager

Install-Package Edi.Captcha

or .NET CLI

dotnet add package Edi.Captcha

1. Register in DI

services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromMinutes(20);
    options.Cookie.HttpOnly = true;
});

services.AddSessionBasedCaptcha();
// Don't forget to add this line in your `Configure` method.
 app.UseSession();

or you can customize the options

services.AddSessionBasedCaptcha(option =>
{
    option.Letters = "2346789ABCDEFGHJKLMNPRTUVWXYZ";
    option.SessionName = "CaptchaCode";
    option.CodeLength = 4;
});

2. Generate Image

Using MVC Controller

private readonly ISessionBasedCaptcha _captcha;

public SomeController(ISessionBasedCaptcha captcha)
{
    _captcha = captcha;
}

[Route("get-captcha-image")]
public IActionResult GetCaptchaImage()
{
    var s = _captcha.GenerateCaptchaImageFileStream(
        100,
        36,
        HttpContext.Session);
    return s;
}

Using Middleware

app.UseSession().UseCaptchaImage(options =>
{
    options.RequestPath = "/captcha-image";
    options.ImageHeight = 36;
    options.ImageWidth = 100;
});

3. Add CaptchaCode Property to Model

[Required]
[StringLength(4)]
public string CaptchaCode { get; set; }

5. View

<div class="col">
    <div class="input-group">
        <div class="input-group-prepend">
            <img id="img-captcha" src="~/captcha-image" />
        </div>
        <input type="text" 
               asp-for="CommentPostModel.CaptchaCode" 
               class="form-control" 
               placeholder="Captcha Code" 
               autocomplete="off" 
               minlength="4"
               maxlength="4" />
    </div>
    <span asp-validation-for="CommentPostModel.CaptchaCode" class="text-danger"></span>
</div>

6. Validate Input

_captcha.ValidateCaptchaCode(model.CommentPostModel.CaptchaCode, HttpContext.Session)

To make your code look more cool, you can also write an Action Filter like this:

public class ValidateCaptcha : ActionFilterAttribute
{
    private readonly ISessionBasedCaptcha _captcha;

    public ValidateCaptcha(ISessionBasedCaptcha captcha)
    {
        _captcha = captcha;
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var captchaedModel =
            context.ActionArguments.Where(p => p.Value is ICaptchable)
                                   .Select(x => x.Value as ICaptchable)
                                   .FirstOrDefault();

        if (null == captchaedModel)
        {
            context.ModelState.AddModelError(nameof(captchaedModel.CaptchaCode), "Captcha Code is required");
            context.Result = new BadRequestObjectResult(context.ModelState);
        }
        else
        {
            if (!_captcha.Validate(captchaedModel.CaptchaCode, context.HttpContext.Session))
            {
                context.ModelState.AddModelError(nameof(captchaedModel.CaptchaCode), "Wrong Captcha Code");
                context.Result = new ConflictObjectResult(context.ModelState);
            }
            else
            {
                base.OnActionExecuting(context);
            }
        }
    }
}

and then

services.AddScoped<ValidateCaptcha>();

and then

public class YourModelWithCaptchaCode : ICaptchable
{
    public string YourProperty { get; set; }

    [Required]
    [StringLength(4)]
    public string CaptchaCode { get; set; }
}

[ServiceFilter(typeof(ValidateCaptcha))]
public async Task<IActionResult> SomeAction(YourModelWithCaptchaCode model)
{
    // ....
}

Refer to https://edi.wang/post/2018/10/13/generate-captcha-code-aspnet-core

About

The Captcha module used in my blog

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C# 75.9%
  • HTML 19.3%
  • CSS 4.0%
  • JavaScript 0.8%