ASP.NET-实现图形验证码
ASP.NET 实现图形验证码能够增强网站安全性,防止机器人攻击。通过生成随机验证码并将其绘制成图像,用户在输入验证码时增加了人机交互的难度。本文介绍了如何使用 C# 和 ASP.NET 创建一个简单而有效的图形验证码系统,包括生成随机验证码、绘制验证码图像以及将图像输出到客户端等步骤。这种验证码系统对于保护网站免受恶意攻击和机器人恶意行为具有重要意义。
一、实现思路
我们需要实现一个防爬虫的可以动态刷新的随机验证码图片。
比如下面这种:
关键点:
- 动态:每次打开页面验证码是变化的,并且验证码在一些事件下会自发刷新成新的验证码,比如在点击、输入错误、页面停靠超时等事件触发时,验证码自动刷新。
- 随机:里面的数字和字母是随机的,是一种强密码,不容易被暴力破解。
- 防爬:防止爬虫通过一些AI识别直接通过,我们需要增加图片的复杂度,例如添加一些干扰性的图案,包括但不限于噪音线、噪点等。
验证码生成成功后,我们还需要将验证码保存到 Session 中,以便后续验证。
二、编写前端代码
思路已经明确,下面,我们来构建图形验证码的前端代码。
前端代码包含 HTML 和 JavaScript 代码。
1、编写HTML代码
HTML代码包含一个简单的验证码输入框和刷新图片按钮的用户界面:
<div class="checkcode"><input type="text" runat="server" id="VercodeText" placeholder="验证码" maxlength="4"><img onclick="changepic(this)" src="/handlers/VerCode.ashx" />
</div>
- <div class="checkcode">:创建一个包含验证码元素的 div 容器,用于样式控制。
- <input type="text" runat="server" id="VercodeText" placeholder="验证码" maxlength="4">:添加一个文本输入框,用于用户输入验证码。设置了ID为 "VercodeText",最大长度为4,同时提供了占位符 "验证码"。
- <img οnclick="changepic(this)" src="/handlers/VerCode.ashx" />:插入一个图片元素,其 src 属性指向验证码处理器 VerCode.ashx。当用户点击该图片时,触发JavaScript函数 changepic 进行验证码图像的刷新。
通过这样的HTML结构,用户可以在输入框中输入验证码,并通过点击图片刷新验证码图像,提供了一种交互式的验证码体验。
2、创建JavaScript函数
创建 changepic 函数方法:
function changepic(obj) {var timestamp = (new Date().getTime()) / 1000;$(obj).attr('src', 'VerCode.ashx?tims=' + timestamp);
}
changepic 函数用于刷新验证码图片,通过在 URL 中添加时间戳的方式,确保每次请求都是唯一的,避免浏览器缓存。
三、编写后端代码
后端代码我们采用C#实现。
1、创建输出图形验证码的接口
创建C#验证码处理器 VerCode.ashx:
using CarRental.Common;
using System;
using System.Drawing;
using System.IO;
using System.Web;namespace Handlers
{public class VerCode : IHttpHandler, System.Web.SessionState.IRequiresSessionState{public void ProcessRequest(HttpContext context){}public bool IsReusable{get{return false;}}}
}
VerCode 类实现了 IHttpHandler 接口,用于处理 HTTP 请求。
2、创建验证码生成方法
/// <summary>
/// 随机构建验证码方法
/// </summary>
/// <returns>返回验证码字符串</returns>
public string CreateCode()
{char code;string checkCode = string.Empty;Random rd = new Random();for (int i = 0; i < 4; i++){int num = rd.Next();int _temp;if (num % 2 == 0){_temp = ('0' + (char)(num % 10));if (_temp == 48 || _temp == 49){_temp += rd.Next(2, 9);}}else{_temp = ('A' + (char)(num % 10));if (rd.Next(0, 2) == 0){_temp = (char)(_temp + 32);}if (_temp == 66 || _temp == 73 || _temp == 79 || _temp == 108 || _temp == 111){_temp++;}}code = (char)_temp;checkCode += code;}return checkCode;
}
CreateCode 方法用于生成随机验证码,包含数字和字母,并进行了一些特殊字符的处理,以增加验证码的复杂性。
3、 绘制验证码图片
① 配置验证码参数
我们先定义验证码图像的宽度、高度、字体大小以及用于生成随机数的 Random 对象。
int codeWeight = 80;
int codeHeight = 22;
int fontSize = 16;
Random rd = new Random();
② 生成验证码字符串
这一步很简单,我们直接调用之前写好的 CreateCode 方法。
string checkCode = CreateCode();
③ 构建验证码背景
创建一个位图对象,并在其上创建图形对象,然后用白色填充图像背景。
Bitmap image = new Bitmap(codeWeight, codeHeight);
Graphics g = Graphics.FromImage(image);
g.Clear(Color.White);
④ 画噪音线
在图像上绘制两条随机颜色的噪音线,增加验证码的复杂性。
for (int i = 0; i < 2; i++)
{int x1 = rd.Next(image.Width);int x2 = rd.Next(image.Width);int y1 = rd.Next(image.Height);int y2 = rd.Next(image.Height);g.DrawLine(new Pen(color[rd.Next(color.Length)]), new Point(x1, y1), new Point(x2, y2));
}
⑤ 画验证码
使用循环逐个绘制验证码字符串中的字符,每个字符使用随机颜色和字体。
for (int i = 0; i < checkCode.Length; i++)
{Color clr = color[rd.Next(color.Length)];Font ft = new Font(font[rd.Next(font.Length)], fontSize);g.DrawString(checkCode[i].ToString(), ft, new SolidBrush(clr), (float)i * 18 + 2, 0);
}
⑥ 画噪音点
在图像上绘制100个随机颜色的噪音点,增加验证码的随机性。
for (int i = 0; i < 100; i++)
{int x = rd.Next(image.Width);int y = rd.Next(image.Height);image.SetPixel(x, y, Color.FromArgb(rd.Next()));
}
⑦ 画边框线
在图像周围绘制银色边框线,使验证码更加清晰。
g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
⑧ 将验证码图像保存到内存流
将生成的验证码图像保存到内存流中,准备输出到客户端。
MemoryStream ms = new MemoryStream(); image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
⑨ 将验证码保存到Session中
将生成的验证码字符串保存到Session中,以便后续验证。
context.Session[ConstantValues.VerCodeSessionName] = checkCode;
⑩ 输出图像到客户端
配置HTTP响应,将验证码图像输出到客户端。
context.Response.ContentType = "Image/Gif";
context.Response.ClearContent();
context.Response.BinaryWrite(ms.ToArray());
最后,别忘记释放图像和图形资源,防止内存泄漏。
finally { image.Dispose(); g.Dispose(); }
4、完整后端代码
完整的 VerCode.cs 代码如下:
using TestMoudle.Common;
using System;
using System.Drawing;
using System.IO;
using System.Web;namespace Handlers
{public class VerCode : IHttpHandler, System.Web.SessionState.IRequiresSessionState{public void ProcessRequest(HttpContext context){int codeWeight = 80;int codeHeight = 22;int fontSize = 16;Random rd = new Random();string checkCode = CreateCode(); //构建验证码字符串Bitmap image = new Bitmap(codeWeight, codeHeight); //构建画图Graphics g = Graphics.FromImage(image); //构建画布g.Clear(Color.White); //清空背景色Color[] color = new Color[] { Color.Red, Color.Black, Color.Green, Color.Blue };string[] font = new string[] { "宋体", "黑体", "楷体" };//画噪音线for (int i = 0; i < 2; i++){int x1 = rd.Next(image.Width);int x2 = rd.Next(image.Width);int y1 = rd.Next(image.Height);int y2 = rd.Next(image.Height);g.DrawLine(new Pen(color[rd.Next(color.Length)]), new Point(x1, y1), new Point(x2, y2));}//画验证码for (int i = 0; i < checkCode.Length; i++){Color clr = color[rd.Next(color.Length)];Font ft = new Font(font[rd.Next(font.Length)], fontSize);g.DrawString(checkCode[i].ToString(), ft, new SolidBrush(clr), (float)i * 18 + 2, 0);}//画噪音点for (int i = 0; i < 100; i++){int x = rd.Next(image.Width);int y = rd.Next(image.Height);image.SetPixel(x, y, Color.FromArgb(rd.Next()));}//画边框线g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);MemoryStream ms = new MemoryStream();try{image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);context.Session[ConstantValues.VerCodeSessionName] = checkCode; //将验证码保存到Session中context.Response.ContentType = "Image/Gif";context.Response.ClearContent();context.Response.BinaryWrite(ms.ToArray());}finally{image.Dispose();g.Dispose();}}public bool IsReusable{get{return false;}}}
}
四、测试效果
我们运行项目,可以看到验证码图像顺利生成了,并且点击可以刷新图片内容。
相关文章:

ASP.NET-实现图形验证码
ASP.NET 实现图形验证码能够增强网站安全性,防止机器人攻击。通过生成随机验证码并将其绘制成图像,用户在输入验证码时增加了人机交互的难度。本文介绍了如何使用 C# 和 ASP.NET 创建一个简单而有效的图形验证码系统,包括生成随机验证码、绘制…...

解决Maven爆红以及解决 Idea 卡在 Resolving问题
关于 Idea 卡在 Resolving(前提是Maven的setting.xml中配置好了阿里云和仓库) 参考文章https://blog.csdn.net/jiangyu1013/article/details/95042611 解决Maven爆红参考文章https://devpress.csdn.net/beijing/656d993b76f0791b6eca7bb0.html?dp_toke…...

MySQL集群 双主架构(配置命令)
CSDN 成就一亿技术人! 今天刚开学第一天给大家分享一期:MySQL集群双主的配置需求和命令 CSDN 成就一亿技术人! 神秘泣男子主页:作者首页 <———— MySQL专栏 :MySQL数据库专栏<———— MySQL双主是一…...

网络安全之安全事件监测
随着人们对技术和智能互联网设备依赖程度的提高,网络安全的重要性也在不断提升。因此,我们需要不断加强网络安全意识和措施,确保网络环境的安全和稳定。 网络安全的重要性包含以下几点: 1、保护数据安全:数据是组织和…...

【BUG 记录】MyBatis-Plus 处理枚举字段和 JSON 字段
【BUG 记录】MyBatis-Plus 处理枚举字段和JSON字段 一、枚举字段(mysql环境已测、postgresql环境已测)1.1 场景1.2 定义枚举常量1.3 配置枚举处理器1.4 测试 二、JSON字段(mysql环境已测)2.1 导包2.2 使用对象接受2.3 测试 三、JS…...

Web性能优化-详细讲解与实用方法-MDN文档学习笔记
Web性能优化 查看更多学习笔记:GitHub:LoveEmiliaForever MDN中文官网 性能优良的网站能够提高访问者留存和用户满意度,减少客户端和服务器之间传输的数据量可降低各方的成本 不同的业务目标和用户需求需要不同的性能度量,要提高…...

组态王连接施耐德M580PLC
组态王连接施耐德M580 网络架构 网线连接PLC和装组态王软件的PC组态设置帮助 可先查看帮助:菜单栏点击【帮助】->【驱动帮助】,在弹出窗口中PLC系列选择莫迪康PLC的“modbusRtu\ASSCII\TCP”查看组态配置流程: 相关说明: 1、…...

pop链构造 [NISACTF 2022]babyserialize
打开题目 题目源代码如下 <?php include "waf.php"; class NISA{public $fun"show_me_flag";public $txw4ever;public function __wakeup(){if($this->fun"show_me_flag"){hint();}}function __call($from,$val){$this->fun$val[0];…...
【VIP专属】Python应用案例——基于Keras, OpenCV和MobileNet口罩佩戴识别
目录 1、导入所需库 2、加载人脸口罩检测数据集 3、对标签进行独热编码...

Doris——荔枝微课统一实时数仓建设实践
目录 一、业务介绍 二、早期架构及痛点 2.1 早期架构 2.2 架构痛点 三、技术选型 四、新的架构及方案 五、搭建经验 5.1 数据建模 5.2 数据开发 5.3 库表设计 5.4 数据管理 5.4.1 监控告警 5.4.2 数据备份与恢复 六、收益总结 七、未来规划 原文大佬这篇Doris腾…...

Stable Diffusion 绘画入门教程(webui)-ControlNet(Inpaint)
上篇文章介绍了语义分割Tile/Blur,这篇文章介绍下Inpaint(重绘) Inpaint类似于图生图的局部重绘,但是Inpain效果要更好一点,和原图融合会更加融洽,下面是案例,可以看下效果(左侧原图…...
LeetCode146: LRU缓存
题目描述 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则…...

【ArcGIS】基于DEM/LUCC等数据统计得到各集水区流域特征
基于DEM/LUCC等数据统计得到各集水区流域特征 提取不同集水区各类土地利用类型比例步骤1:划分集水区为独立面单元步骤2:批量掩膜提取得到各集水区土地利用类型比例步骤3:导入各集水区LUCC数据并统计得到各类型占比 提取坡度特征流域面坡度河道…...
vue3中安装并使用CSS预处理器Sass的方法介绍
文章目录 Sass是什么?为什么使用Sass?安装sass1、安装sass2、编写全局css变量/全局mixin3、vite引入并使用4、按需引入并使用 sass语法1、变量创建一个变量使用变量变量作用域 2、数学计算两个Sass有关于数学计算的“陷阱” 3、嵌套4、Imports sass中文官网 Sass是…...
过滤器(Filter)
过滤器(Filter) 1. 基本概念 过滤器(Filter)是拦截 Request 请求的对象:在用户的请求访问资源前处理 ServletRequest 和 ServletResponse 。 Filter 相关的接口有:Filter、FilterConfig、FilterChain 。…...

AMRT3D数字孪生引擎详解
AMRT 3D数字孪生引擎介绍 AMRT3D引擎是一款融合了眸瑞科技的AMRT格式与轻量化处理技术为基础,以降本增效为目标,支持多端发布的一站式纯国产自研的CS架构项目开发引擎。 引擎包括场景搭建、UI拼搭、零代码交互事件、光影特效组件、GIS/BIM组件、实时数据…...
Sqlite数据库详解
1.关于Sqlite SQLite 是一个进程内库,它实现了一个独立的、无服务器的、零配置的事务性 SQL 数据库引擎。 SQLite的代码属于公共领域,因此对 用于任何目的,商业或私人目的。 SQLite是世界上部署最广泛的数据库 应用程序比我们能做的要多 计数…...

基于YOLOv8深度学习+Pyqt5的电动车头盔佩戴检测系统
wx供重浩:创享日记 对话框发送:225头盔 获取完整源码源文件已标注的数据集(1463张)源码各文件说明配置跑通说明文档 若需要一对一远程操作在你电脑跑通,有偿59yuan 效果展示 基于YOLOv8深度学习PyQT5的电动车头盔佩戴检…...

【数据结构】B树,B+树,B*树
文章目录 一、B树1.B树的定义2.B树的插入3.B树的中序遍历 二、B树和B*树1.B树的定义2.B树的插入3.B*树的定义4.B树系列总结 三、B树与B树的应用 一、B树 1.B树的定义 1. 在内存中搜索效率高的数据结构有AVL树,红黑树,哈希表等,但这是在内存…...

常用实验室器皿耐硝酸盐酸进口PFA材质容量瓶螺纹盖密封效果好
PFA容量瓶规格参考:10ml、25ml、50ml、100ml、250ml、500ml、1000ml。 别名可溶性聚四氟乙烯容量瓶、特氟龙容量瓶。常用于ICP-MS、ICP-OES等痕量分析以及同位素分析等实验,也可在地质、电子化学品、半导体分析测试、疾控中心、制药厂、环境检测中心等机…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...