using Microsoft.AspNetCore.Mvc;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
[ApiController]
[Route("api/[controller]")]
public class CaptchaController : ControllerBase
{
// 存储验证码的内存缓存(生产环境建议用分布式缓存)
private static readonly ConcurrentDictionary _captchaStore = new();
// 获取验证码图片
[HttpGet("image/{token}")]
public IActionResult GetCaptchaImage(string token, int width = 120, int height = 40)
{
// 生成4位数字+字母验证码
var captchaCode = GenerateRandomCode(4);
_captchaStore[token] = captchaCode;
// 创建位图
using var bitmap = new Bitmap(width, height);
using var g = Graphics.FromImage(bitmap);
// 设置背景色
g.Clear(Color.White);
// 绘制干扰线
var random = new Random();
for (int i = 0; i < 5; i++)
{
using var pen = new Pen(Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)), 1);
g.DrawLine(pen, random.Next(width), random.Next(height), random.Next(width), random.Next(height));
}
// 绘制验证码文字
using var font = new Font("Arial", 18, FontStyle.Bold | FontStyle.Italic);
for (int i = 0; i < captchaCode.Length; i++)
{
using var brush = new SolidBrush(Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)));
// 文字随机偏移和旋转
var x = 10 + i * 25;
var y = random.Next(5, 15);
g.RotateTransform(random.Next(-15, 15));
g.DrawString(captchaCode[i].ToString(), font, brush, x, y);
g.ResetTransform();
}
// 绘制干扰点
for (int i = 0; i < 200; i++)
{
bitmap.SetPixel(random.Next(width), random.Next(height), Color.FromArgb(random.Next(256)));
}
// 输出图片流
using var ms = new MemoryStream();
bitmap.Save(ms, ImageFormat.Png);
return File(ms.ToArray(), "image/png");
}
// 验证验证码
[HttpPost("verify/{token}")]
public IActionResult VerifyCaptcha(string token, [FromBody] string inputCode)
{
if (_captchaStore.TryGetValue(token, out var realCode))
{
_captchaStore.TryRemove(token, out _); // 验证后立即失效
if (string.Equals(realCode, inputCode, StringComparison.OrdinalIgnoreCase))
{
return Ok(new { Success = true, Message = "验证通过" });
}
}
return Ok(new { Success = false, Message = "验证码错误或已过期" });
}
// 生成随机验证码
private string GenerateRandomCode(int length)
{
var chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; // 排除易混淆字符
var random = new Random();
var code = new char[length];
for (int i = 0; i < length; i++)
{
code[i] = chars[random.Next(chars.Length)];
}
return new string(code);
}
}
注意:ASP.NET Core 项目需安装System.Drawing.Common NuGet 包。