Asp.net mvc 如何在asp.net核心asp.net Mvc 6中创建验证码?
我正在asp.net core中开发asp.net MVC 6应用程序,我想为我的登录页面创建验证码。在以前的.net框架中,我使用system.drawing创建验证码,但由于在.net框架核心中我们没有system.drawing,如何实现这一点 一个解决方案是引用完整的.net框架,但这不是我想要的。我想使用核心框架 另一个是使用.NETFramework6和MVC5创建一个项目,并使用WebAPI获取验证码图像,但这也不是我想要的Asp.net mvc 如何在asp.net核心asp.net Mvc 6中创建验证码?,asp.net-mvc,asp.net-core,asp.net-core-mvc,captcha,Asp.net Mvc,Asp.net Core,Asp.net Core Mvc,Captcha,我正在asp.net core中开发asp.net MVC 6应用程序,我想为我的登录页面创建验证码。在以前的.net框架中,我使用system.drawing创建验证码,但由于在.net框架核心中我们没有system.drawing,如何实现这一点 一个解决方案是引用完整的.net框架,但这不是我想要的。我想使用核心框架 另一个是使用.NETFramework6和MVC5创建一个项目,并使用WebAPI获取验证码图像,但这也不是我想要的 还有别的解决办法吗 请按照以下步骤在Mvc中创建验证码
还有别的解决办法吗 请按照以下步骤在Mvc中创建验证码
我在ASP.NET核心应用程序中实现了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>
}
请注意,要在控制器上调用扩展方法,必须使用this关键字
我目前在多个项目中使用它,因此如果您需要查看更多代码,最简单的是在我的项目中,但我也在使用它我为recaptcha制作了一个与aspnetcore一起使用的包装器,请查看它,在 简而言之,要使用它,您需要执行以下操作:
public void配置服务(IServiceCollection服务)
{
services.AddMvc();
services.AddRecaptcha(新的RecaptchaOptions
{
SiteKey=Configuration[“Recaptcha:SiteKey”],
SecretKey=Configuration[“Recaptcha:SecretKey”]
});
}
二,。在“_ViewImports.cshtml”文件中添加。
三,。在你看来。
你可以不用任何特殊的包装。根据recaptcha网站- 客户端集成 将此代码段粘贴到HTML模板的关闭标记
之前:
<script src='https://www.google.com/recaptcha/api.js'></script>
将此代码段粘贴到要显示reCAPTCHA小部件的末尾:
<div class="g-recaptcha" data-sitekey="YOURSITEKEY"></div>
服务器端集成
当您的用户提交集成了reCAPTCHA的表单时,您将得到一个名为“g-reCAPTCHA-response”的字符串作为有效负载的一部分。为了检查Google是否已验证该用户,请发送一个包含以下参数的POST请求:
网址:
机密(必需):您的机密密钥
响应(必需):“g-recaptcha-response”的值
remoteip:最终用户的ip地址。为了方便起见,您可以使用该组件,您可以查看如何在该链接中使用 我已经做到了: 添加对System.Drawing.Common的引用 如果在linux上安装linux LIB:
sudo apt install libc6-dev
sudo apt install libgdiplus
[HttpPost]
[异名]
[ValidateAntiForgeryToken]
公共异步任务寄存器(RegisterViewModel模型,字符串returnUrl=null)
{
ViewData[“ReturnUrl”]=ReturnUrl;
var validCaptchaText=Request.Cookies[“cv”];//已添加
if(ModelState.IsValid&&model.usercaptchattext.Hash()+“”==validcaptchattext)//已更改
{
var user=new-AppUser{UserName=model.Email,Email=model.Email};
var result=await\u userManager.CreateAsync(用户、模型、密码);
if(result.successed)
{
_logger.LogInformation(“用户使用密码创建了一个新帐户”);
var code=wait_userManager.GenerateEmailConfirmationTokenAsync(用户);
var callbackUrl=Url.EmailConfirmationLink(user.Id、code、Request.Scheme);
wait_emailSender.sendmailconfirmationasync(model.Email,callbackUrl);
wait _signInManager.SignInAsync(用户,ispersist:false);
_logger.LogInformation(“用户使用密码创建了一个新帐户”);
返回重定向到本地(returnUrl);
}
加法器(结果);
}
//如果我们走到这一步,有些东西失败了,重新显示形式
返回视图(模型);
}
验证码
宽度:24px;高度:12px;显示:内联块;背景色:#a52a2a“>
宽度:24px;高度:12px;显示:内联块;背景色:#7cfc00“>
宽度:24px;高度:12px;显示:内联块;背景色:#ff7f50“>
登记
完成。我正在使用新版本的.net framework。您的解决方案是针对mvc 5的,而不是针对您的mvc 6.tnx解决方案。但是我不想从不同的服务器获取验证码图像,我想在我的项目中创建它。此时,我创建了另一个项目(一个WebAPI项目),它为我提供了一个图像。就像你建议的recaptcha。不确定它是否可以使用,但也许看看这个,我知道他们正在致力于.NET核心支持,不确定ImageProcessor已经支持.NET核心有多远了。不幸的是,它无法(AFAIK)绘制“仅”操作现有图像我们可以使用服务。AddHttpContextAccessor();在ConfigureServices方法和_accessor.HttpContext.Connection.RemoteIpAddress.ToString()中;在我们的PageModel中,获取要发送到recaptcha验证的remoteIp。正如我在问题中提到的,我创建了一个不同的项目,并按照您的方式实现
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);
}
}
@addTagHelper *, PaulMiami.AspNetCore.Mvc.Recaptcha
<form asp-controller="Home" asp-action="Index" method="post">
<recaptcha />
<input type="submit" value="submit" />
</form>
@section Scripts {
<recaptcha-script />
}
[ValidateRecaptcha]
[HttpPost]
public IActionResult Index(YourViewModel viewModel)
{
if (ModelState.IsValid)
{
return new OkResult();
}
return View();
}
<script src='https://www.google.com/recaptcha/api.js'></script>
<div class="g-recaptcha" data-sitekey="YOURSITEKEY"></div>
sudo apt install libc6-dev
sudo apt install libgdiplus
[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);
}
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;
}
}
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;
}
}
[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);
}
<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>