驗證碼防止暴力破解、機器註冊、垃圾留言。本文比較三種 ASP.NET 驗證碼實作方式:第三方控制項、ASHX 動態圖片 (Session/ Cookie)、Generic Handler,分析優缺點與適用場景。

public partial class Tools_CheckCode : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
CreateCheckCodeImage(GenerateCheckCode());
}
private string GenerateCheckCode() {
string code = "";
Random r = new Random();
for (int i = 0; i < 5; i++) {
int n = r.Next();
char c = (n % 2 == 0) ? (char)('0' + n % 10) : (char)('A' + n % 26);
code += c;
}
Response.Cookies.Add(new HttpCookie("CheckCode", code));
return code;
}
private void CreateCheckCodeImage(string code) {
Bitmap img = new Bitmap((int)Math.Ceiling(code.Length * 12.5), 22);
Graphics g = Graphics.FromImage(img);
try {
g.Clear(Color.White);
// 背景干擾線
Random r = new Random();
for (int i = 0; i < 25; i++) {
g.DrawLine(new Pen(Color.GreenYellow),
r.Next(img.Width), r.Next(img.Height),
r.Next(img.Width), r.Next(img.Height));
}
// 文字
Font font = new Font("Verdana", 12, FontStyle.Bold | FontStyle.Italic);
LinearGradientBrush brush = new LinearGradientBrush(
new Rectangle(0, 0, img.Width, img.Height), Color.Blue, Color.DarkRed, 1.2f, true);
g.DrawString(code, font, brush, 2, 2);
// 前景干擾點
for (int i = 0; i < 80; i++) {
img.SetPixel(r.Next(img.Width), r.Next(img.Height), Color.FromArgb(r.Next()));
}
// 邊框
g.DrawRectangle(new Pen(Color.Red), 0, 0, img.Width - 1, img.Height - 1);
MemoryStream ms = new MemoryStream();
img.Save(ms, ImageFormat.Gif);
Response.ClearContent();
Response.ContentType = "image/gif";
Response.BinaryWrite(ms.ToArray());
} finally {
g.Dispose(); img.Dispose();
}
}
}
換一張
if (Request.Cookies["CheckCode"] != null
&& Request.Form["txtCode"].ToUpper() == Request.Cookies["CheckCode"].Value.ToUpper()) {
// 通過
}

<%@ WebHandler Language="C#" Class="ValidateImageHandler" %>
using System;
using System.Web;
using System.Web.SessionState;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
public class ValidateImageHandler : IHttpHandler, IRequiresSessionState {
int _length = 5;
string _sessionKey = "ValidateCode";
public void ProcessRequest(HttpContext context) {
context.Response.ContentType = "image/gif";
Bitmap bmp = new Bitmap(200, 60);
Graphics g = Graphics.FromImage(bmp);
g.FillRectangle(new SolidBrush(Color.YellowGreen), 0, 0, 200, 60);
Font font = new Font(FontFamily.GenericSerif, 48, FontStyle.Bold, GraphicsUnit.Pixel);
Random r = new Random();
string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < _length; i++) {
char c = chars[r.Next(chars.Length)];
sb.Append(c);
g.DrawString(c.ToString(), font, new SolidBrush(Color.Blue), i * 38, r.Next(0, 15));
}
// 干擾線
Pen pen = new Pen(new SolidBrush(Color.Blue), 2);
for (int i = 0; i < 10; i++) {
g.DrawLine(pen,
new Point(r.Next(199), r.Next(59)),
new Point(r.Next(199), r.Next(59)));
}
bmp.Save(context.Response.OutputStream, ImageFormat.Gif);
context.Session[_sessionKey] = sb.ToString();
context.Response.End();
}
public bool IsReusable { get { return true; } }
}
if (Session["ValidateCode"] != null && Request.Form["txtCode"].ToUpper() == Session["ValidateCode"].ToString().ToUpper()) { ... }

| 維度 | GSC 控制項 | ASPX/ASHX + Cookie | Generic Handler + Session |
|---|---|---|---|
| 整合難度 | 極低 (拖拉) | 中 (需建立頁面/Handler) | 中 (需建立 .ashx) |
| 客製化程度 | 低 (僅屬性設定) | 高 (完整控制繪圖邏輯) | 高 (完整控制繪圖邏輯) |
| 儲存機制 | 元件內部 | Cookie (客戶端) | Session (伺服器端) |
| 安全性 | 低 (易被破解) | 中 (Cookie 可被竄改) | 較高 (Session 伺服器端) |
| 效能 | 一般 | 較好 (Page 生命週期) | 最佳 (Handler 輕量) |
| 可重用性 | 高 (控制項) | 中 (需複製頁面) | 高 (Handler 可多專案共用) |
| 支援動態 GIF | 否 | 否 | 需自行實作 |
Session.Remove() 防重放教學階段建議自行實作 Handler + Session 方式,深入理解繪圖邏輯與驗證流程。生產環境若無特殊客製需求,建議整合成熟的驗證碼服務 (reCAPTCHA/hCaptcha),安全性、維護性、使用者體驗均優於自建方案。動態 GIF、行為分析、無感驗證是未來演進方向。