首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET 三種驗證碼實作比較:GSC 控制項、ASHX 動態圖片、ASHX Handler

     編輯:ASP.NET 基礎

前言

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

方式一:GSC_WebControlLibrary 控制項

特點

  • 拖拉即用,屬性視窗設定所有參數
  • 無法自訂演算法、字型、干擾樣式
  • 圖片品質一般,易被 OCR 識別

GSC 控制項效果

方式二:ASHX 動態圖片 + Cookie 儲存

CheckCode.ashx

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()) {
    // 通過
}

ASHX+Cookie 效果

方式三:Generic Handler (ASHX) + Session 儲存

ValidateImageHandler.ashx

<%@ 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()) { ... }

Handler+Session 效果

三種方式詳細比較

維度GSC 控制項ASPX/ASHX + CookieGeneric Handler + Session
整合難度極低 (拖拉)中 (需建立頁面/Handler)中 (需建立 .ashx)
客製化程度低 (僅屬性設定)高 (完整控制繪圖邏輯)高 (完整控制繪圖邏輯)
儲存機制元件內部Cookie (客戶端)Session (伺服器端)
安全性低 (易被破解)中 (Cookie 可被竄改)較高 (Session 伺服器端)
效能一般較好 (Page 生命週期)最佳 (Handler 輕量)
可重用性高 (控制項)中 (需複製頁面)高 (Handler 可多專案共用)
支援動態 GIF否否需自行實作

安全性最佳實務

  • 儲存端:優先 Session > Cookie,驗證後立即 Session.Remove() 防重放
  • 字元集:排除易混淆字元 (0/O, 1/I/l, 8/B, 5/S, 2/Z)
  • 干擾強度:背景線、前景點、扭曲、噪點、隨機字型/大小/顏色/旋轉
  • 限流:同 IP 分鐘請求次數限制,失敗 N 次鎖定帳號/IP
  • 現代替代:reCAPTCHA v3 (行為分析)、hCaptcha、滑塊/點選/圖標驗證

結語

教學階段建議自行實作 Handler + Session 方式,深入理解繪圖邏輯與驗證流程。生產環境若無特殊客製需求,建議整合成熟的驗證碼服務 (reCAPTCHA/hCaptcha),安全性、維護性、使用者體驗均優於自建方案。動態 GIF、行為分析、無感驗證是未來演進方向。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved