YPE html>
《.Net Core 之 图形验证码》
在Web开发中,验证码是防止恶意攻击(如暴力破解、自动化脚本等)的重要安全机制。图形验证码通过生成包含随机字符的图片,要求用户识别并输入,从而验证用户是否为真实人类。本文将详细介绍如何在.Net Core项目中实现图形验证码功能,涵盖验证码生成、验证逻辑以及前后端交互的全流程。
一、图形验证码的核心原理
图形验证码的核心在于生成一张包含随机字符的图片,并将这些字符存储在服务端(如Session或缓存中),用户输入后与存储的字符进行比对。其实现通常包含以下步骤:
- 生成随机字符(字母、数字或混合)。
- 创建图片画布,设置背景色、干扰线、噪点等增强安全性。
- 将字符绘制到图片上,可添加扭曲、旋转等变形效果。
- 将图片以二进制流形式返回给前端。
- 用户输入后,服务端验证输入是否与存储的字符匹配。
二、.Net Core中的实现方案
在.Net Core中,可通过`System.Drawing`(Windows环境)或`SkiaSharp`(跨平台)库生成图片。以下以`System.Drawing`为例(需安装`System.Drawing.Common` NuGet包)。
1. 创建验证码生成服务
新建一个`CaptchaService`类,封装验证码生成逻辑:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
public class CaptchaService
{
private const int Width = 120;
private const int Height = 40;
private const int CodeLength = 4;
private const string CharSet = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; // 排除易混淆字符
public (string Code, byte[] ImageBytes) GenerateCaptcha()
{
// 生成随机字符
var random = new Random();
var code = new char[CodeLength];
for (int i = 0; i
2. 创建API控制器
在.Net Core的`Controllers`文件夹下创建`CaptchaController`,提供验证码生成和验证接口:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
[ApiController]
[Route("api/[controller]")]
public class CaptchaController : ControllerBase
{
private readonly CaptchaService _captchaService;
private const string CaptchaKey = "CaptchaCode";
public CaptchaController(CaptchaService captchaService)
{
_captchaService = captchaService;
}
[HttpGet("generate")]
public IActionResult GenerateCaptcha()
{
var (code, imageBytes) = _captchaService.GenerateCaptcha();
// 存储验证码到Session(需配置Session中间件)
HttpContext.Session.SetString(CaptchaKey, code);
// 返回图片
return File(imageBytes, "image/jpeg");
}
[HttpPost("validate")]
public IActionResult ValidateCaptcha([FromBody] CaptchaValidationModel model)
{
if (model == null || string.IsNullOrWhiteSpace(model.UserInput))
{
return BadRequest("输入不能为空");
}
var storedCode = HttpContext.Session.GetString(CaptchaKey);
if (storedCode == null)
{
return BadRequest("验证码已过期");
}
bool isValid = storedCode.Equals(model.UserInput, StringComparison.OrdinalIgnoreCase);
if (isValid)
{
// 验证通过后清除Session中的验证码(防止重复使用)
HttpContext.Session.Remove(CaptchaKey);
return Ok(new { success = true });
}
else
{
return BadRequest(new { success = false, message = "验证码错误" });
}
}
}
public class CaptchaValidationModel
{
public string UserInput { get; set; }
}
3. 配置Session中间件
在`Startup.cs`中配置Session支持(.Net Core 3.1+):
public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedMemoryCache(); // 使用内存缓存存储Session
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(5); // Session过期时间
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
services.AddControllers();
services.AddSingleton();
}
在`Configure`方法中启用Session:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...其他中间件
app.UseSession();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
三、前端集成示例
前端通过调用API获取验证码图片并提交用户输入。以下以HTML+JavaScript为例:
验证码示例
四、安全增强建议
- 限制尝试次数:记录用户IP的验证失败次数,超过阈值后暂时禁止验证。
- 验证码过期时间:设置Session过期时间(如5分钟),防止长时间有效。
- 复杂度提升:增加字符长度、添加更多干扰元素(如弧线、波浪变形)。
- 跨平台兼容:若需部署到Linux,使用`SkiaSharp`替代`System.Drawing`。
- HTTPS加密:确保验证码图片和验证接口通过HTTPS传输,防止中间人攻击。
五、常见问题与解决
问题1:Linux环境下`System.Drawing`报错。
解决:安装`libgdiplus`依赖(Ubuntu下执行`sudo apt-get install libgdiplus`),或改用`SkiaSharp`。
问题2:验证码图片显示为空。
解决:检查API返回的`Content-Type`是否为`image/jpeg`,确保内存流未被提前释放。
问题3:Session无法存储验证码。
解决:确认已调用`app.UseSession()`,并检查Session配置是否正确。
六、总结
本文详细介绍了在.Net Core中实现图形验证码的完整流程,包括验证码生成、服务端存储、前后端交互以及安全增强措施。通过结合`System.Drawing`或`SkiaSharp`库,可以灵活定制验证码的复杂度。实际应用中,还需根据业务需求调整验证码的有效期、尝试限制等策略,以平衡安全性和用户体验。
关键词:.Net Core、图形验证码、System.Drawing、SkiaSharp、Session验证、安全机制、前后端交互
简介:本文详细讲解了.Net Core中图形验证码的实现方法,包括生成逻辑、服务端存储、API接口设计以及前端集成,同时提供了安全增强建议和常见问题解决方案。