【问题标题】:How to Create captcha in asp.net core Asp.net Mvc 6?如何在 asp.net core Asp.net Mvc 6 中创建验证码?
【发布时间】:2016-09-10 11:14:59
【问题描述】:

我正在 asp.net core 中开发 asp.net MVC 6 应用程序,我想为我的登录页面创建一个验证码。在以前的 .net 框架中,我使用 system.drawing 创建验证码,但由于在 .net 框架核心中我们没有 system.drawing ,我该如何实现呢?

一种解决方案是参考完整的 .net 框架,但这不是我想要的。我想使用核心框架。

另一个是使用 .net framework 6 和 Mvc 5 创建一个项目,并使用 web api 获取验证码图像,但这也不是我想要的。

还有其他解决方案吗?

【问题讨论】:

标签: asp.net-mvc asp.net-core asp.net-core-mvc captcha


【解决方案1】:

请按照以下步骤在 Mvc 中创建验证码。

  1. 像这样将 CaptchaMvc 库添加到应用程序中的参考层。

  2. 现在像这样创建索引视图。

查看

 @using CaptchaMvc.HtmlHelpers  
 @using MathCaptcha;  
 @using CaptchaMvc;  

 @using (Html.BeginForm()) {  
 @Html.ValidationSummary(true)  

<fieldset>  
    <legend>Captcha Example</legend>  

    @Html.MathCaptcha()  

    @*@Html.Captcha(3)*@  

    <input type="submit" value="Send" />  

 </fieldset>  
 }  

@Html.MathCaptcha() 辅助类然后它将生成一个数学验证码。如果您使用@Html。 Captcha(3) 辅助类,然后它将生成一个 Char CAPTCHA。 3 是验证码的长度。

  1. 在 post action 方法中,我编写了 CAPTCHA 验证代码。

     [HttpPost]  
     public ActionResult Index(string empty)  
     {  
        // Code to validate the CAPTCHA image
        if (this.IsCaptchaValid("Captcha not valid"))  
        {  
    
            // do your stuff  
        }  
    
        return View();  
     }  
    

【讨论】:

  • 我正在使用新版本的 .net framework 。您的解决方案适用于 mvc 5 而不是 mvc 6。
【解决方案2】:

我在我的 ASP.NET Core 应用程序中实现了 Recaptcha。在我的登录视图中:

@if (Model.RecaptchaSiteKey.Length > 0)
{
    <script src='https://www.google.com/recaptcha/api.js'></script>
}


@if (Model.RecaptchaSiteKey.Length > 0)
{
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <div class="g-recaptcha" data-sitekey="@Model.RecaptchaSiteKey"></div>
            @Html.ValidationMessage("recaptchaerror", new { @class = "text-danger" })
        </div>
    </div>

}

我在控制器上实现了一个扩展方法,因此我可以从我正在使用它的任何控制器轻松验证验证码服务器端。

public static async Task<RecaptchaResponse> ValidateRecaptcha(
    this Controller controller,
    HttpRequest request,
    string secretKey)
{
    var response = request.Form["g-recaptcha-response"];
    var client = new HttpClient();
    string result = await client.GetStringAsync(
        string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}",
            secretKey,
            response)
            );

    var captchaResponse = JsonConvert.DeserializeObject<RecaptchaResponse>(result);

    return captchaResponse;
}

然后,我的 AccountController 中的 login post 方法中的这个 sn-p 使用该扩展方法检查验证码服务器端:

if ((Site.CaptchaOnLogin) && (Site.RecaptchaPublicKey.Length > 0))
{
    var recpatchaSecretKey = Site.RecaptchaPrivateKey;
    var captchaResponse = await this.ValidateRecaptcha(Request, recpatchaSecretKey);

    if (!captchaResponse.Success)
    {
        ModelState.AddModelError("recaptchaerror", "reCAPTCHA Error occured. Please try again");
        return View(model);
    }
}

请注意,要在控制器上调用扩展方法,您必须使用 this 关键字。

我目前在多个项目中使用它,所以如果您需要查看更多代码,最简单的是在我的SimpleAuth 项目中,但我也在使用它cloudscribe

【讨论】:

  • tnx 为您提供解决方案。但我不想从不同的服务器获取验证码图像,我想在我的项目中创建它。此时我创建了另一个项目(一个 web api 项目),它给了我一个图像。喜欢你建议的recaptcha。
  • 不确定它是否可以使用,但也许看看这个github.com/JimBobSquarePants/ImageProcessor 我知道他们正在努力支持.NET Core,不知道他们走了多远
  • ImageProcessor 已经支持 .NET Core。不幸的是,它无法(AFAIK)绘制,“仅”操纵现有图像
  • 我们可以使用 services.AddHttpContextAccessor();在 ConfigureServices 方法和 _accessor.HttpContext.Connection.RemoteIpAddress.ToString();在我们的 PageModel 中获取要发送到 recaptcha 验证的 remoteIp。来源edi.wang/post/2017/10/16/get-client-ip-aspnet-20
【解决方案3】:

我为 recaptcha 制作了一个可与 aspnetcore 一起使用的包装器,请查看 https://www.nuget.org/packages/PaulMiami.AspNetCore.Mvc.Recaptcha 并在 https://github.com/PaulMiami/reCAPTCHA/wiki/Getting-started 处提供一些文档

简而言之,您需要执行以下操作才能使用它:

  1. 在您的 Startup 类中设置服务。
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddRecaptcha(new RecaptchaOptions
    {
        SiteKey = Configuration["Recaptcha:SiteKey"],
        SecretKey = Configuration["Recaptcha:SecretKey"]
    });
}

2。在您的“_ViewImports.cshtml”文件中添加。

@addTagHelper *, PaulMiami.AspNetCore.Mvc.Recaptcha

3。在你看来。

<form asp-controller="Home" asp-action="Index" method="post">
    <recaptcha />
    <input type="submit" value="submit" />
</form>
@section Scripts {
    <recaptcha-script />
}

4。在你的控制器中。

[ValidateRecaptcha]
[HttpPost]
public IActionResult Index(YourViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        return new OkResult();
    }

    return View();
}

【讨论】:

  • 如果recaptcha submissin 错误,您将如何更改错误消息?
【解决方案4】:

您可以在没有任何特殊包装的情况下做到这一点。根据recaptcha网站-

客户端集成

将此 sn-p 粘贴在 HTML 模板上的结束 &lt;/head&gt; 标记之前:

<script src='https://www.google.com/recaptcha/api.js'></script>

将此 sn-p 粘贴到您希望 reCAPTCHA 小部件出现的位置的末尾:

<div class="g-recaptcha" data-sitekey="YOURSITEKEY"></div>

服务器端集成

当您的用户提交您集成了 reCAPTCHA 的表单时,您将在负载中获得一个名为“g-recaptcha-response”的字符串。要检查 Google 是否已验证该用户,请发送带有以下参数的 POST 请求:

网址:https://www.google.com/recaptcha/api/siteverify

秘密(必需):YOURSECRETKEY

response(必填):“g-recaptcha-response”的值。

remoteip:最终用户的IP地址。

【讨论】:

  • 正如我在问题中提到的那样,我创建了一个不同的项目并使用我自己的服务器实现了您描述的方式,但我想在 mvc 6 和新的 .net 新技术中获取验证码( asp.net 核心)
  • 我描述的方法适用于 MVC 6 和 .NET Core。我已经在运行它了。如果您正在寻找 Nuget 包,我可以让 @PaulMiami 创建的包也能正常工作。
  • 您向 web api 发出请求并获取图像,并且为了检查验证码的正确性,您再次请求 web api,他们为您完成了工作,我知道这一点,我实现了它与我自己的网络 api。我想要的是使用 system.draw 的替代库。因为.net core 没有实现它。
  • 不会在页面源中显示 [data-sitekey="YOURSITEKEY"] 属性以供其他人使用吗?
【解决方案5】:

为了简单起见,您可以使用该组件,您可以在该链接中查看如何使用 https://www.nuget.org/packages/IgniteCaptcha/1.0.0

【讨论】:

    【解决方案6】:

    我已经这样做了:

    添加对 System.Drawing.Common 的引用

    如果在 linux 上安装 linux 库:

    sudo apt install libc6-dev
    sudo apt install libgdiplus
    
    1. 在 AccountController 中
            [AllowAnonymous]
            public async Task<IActionResult> GetCaptchaImage()
            {
                var validate = "";
                var bmp = ImageCaptcha.Generate(200, 150, out validate);
    
                using (MemoryStream ms = new MemoryStream())
                {
                    bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
                    result.Content = new ByteArrayContent(ms.ToArray());
                    result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
                    SetCookie("CV", validate.Hash()+"");
                    return File(ms.ToArray(),"image/png");
                }
            }
    
            // move to base controller
            public void SetCookie(string key, string value, int? expireTime = null)
            {
                CookieOptions option = new CookieOptions();
    
                if (expireTime.HasValue)
                    option.Expires = DateTime.Now.AddMinutes(expireTime.Value);
                else
                    option.Expires = DateTime.Now.AddMilliseconds(5 * 60 * 1000);
    
                Response.Cookies.Append(key, value, option);
            }
    
    
    

    将此类添加到项目中 - 在 mem 中生成随机旋转的字母 bmp:

    public static class ImageCaptcha
        {
    
            public static Bitmap Generate(int w, int h, out string validate)
            {
                Bitmap bmp = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    
                Graphics graphics = Graphics.FromImage(bmp);
                var brush = new[] { Brushes.Brown, Brushes.LawnGreen, Brushes.Blue, Brushes.Coral};
                var rand = new Random((int)DateTime.Now.Ticks);
                validate = null;
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    for (int i = 0; i < 4; i++)
                    {
                        var text = Convert.ToChar( rand.Next(97, 122)).ToString();
                        validate += text;
                        if(i==0) g.TranslateTransform(bmp.Width / 2, bmp.Height / 2);
                        g.RotateTransform(40 * 5 * rand.Next(1, 6));
                        var font = new Font("Arial", h * 0.25f + 8 * rand.Next(1, 6), FontStyle.Bold);
                        SizeF textSize = g.MeasureString(text, font);
                        g.DrawString(text, font, brush[i],15*(i+1) -(textSize.Width / 2), -(textSize.Height / 2));
                    }
                }
    
                return bmp;
            }
    
        }
    

    添加此实用程序类以轻松获取 md5 哈希:

    public static partial class H
    {
        public static int Hash(this string value)
        {
            MD5 md5Hasher = MD5.Create();
            var hashed = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(value));
            var ivalue = BitConverter.ToInt32(hashed, 0);
            return ivalue;
        }
    }
    
    1. 对此进行更改注册操作,请参阅 cmets - 添加、更改:
            [HttpPost]
            [AllowAnonymous]
            [ValidateAntiForgeryToken]
            public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
            {
                ViewData["ReturnUrl"] = returnUrl;
                var validCaptchaText = Request.Cookies["cv"]; //added
                if (ModelState.IsValid && model.UserCaptchaText.Hash()+""==validCaptchaText) //changed
                {
                    var user = new AppUser { UserName = model.Email, Email = model.Email };
                    var result = await _userManager.CreateAsync(user, model.Password);
                    if (result.Succeeded)
                    {
                        _logger.LogInformation("User created a new account with password.");
    
                        var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                        var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
                        await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);
    
                        await _signInManager.SignInAsync(user, isPersistent: false);
                        _logger.LogInformation("User created a new account with password.");
                        return RedirectToLocal(returnUrl);
                    }
                    AddErrors(result);
                }
    
                // If we got this far, something failed, redisplay form
                return View(model);
            }
    
    1. 在“确认密码”之后的注册视图中
                    <div class="form-group">
                        <label>Captcha</label><br />
                        <img style="width:100%; border:solid 1px #ced4da" height="150" src="@Url.Action("GetCaptchaImage")" />
                        <span asp-validation-for="ConfirmPassword" class="text-danger"></span>
                        <ul style="list-style-type:none">
                            <li style="width:24px;height:12px; display:inline-block; background-color:#a52a2a "></li>
                            <li style="width:24px;height:12px; display:inline-block; background-color:#7cfc00 "></li>
                            <li style="width:24px;height:12px; display:inline-block; background-color:#0000ff "></li>
                            <li style="width:24px;height:12px; display:inline-block; background-color:#ff7f50 "></li>
                        </ul>
                    </div>
    
                    <div class="form-group">
                        <label asp-for="UserCaptchaText"></label>
                        <input asp-for="UserCaptchaText" class="form-control" />
                    </div>
    
                    <button style="color:white; background-color:#4a7dbc" type="submit" class="btn btn-default">Register</button>
    

    完成了。

    【讨论】:

      猜你喜欢
      • 2021-12-13
      • 2022-01-21
      • 1970-01-01
      • 2022-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多