[ASP.Net] Tạo captcha đơn giản cho trang web

Các trang web hiện nay sử dụng captcha rất phổ biến để tránh tình trạng đăng kí hoặc đăng nhập tự động (không phải do người dùng tự thao tác) một cách tràn lan. Captch thường có dạng một hình ảnh hoặc đoạn flash chứa những kí tự ngẫu nhiên được làm biến dạng nhằm gây khó khăn cho các chương trình có khả năng nhận diện kí tự.

Trong bài viết này tôi sẽ hướng dẫn tạo chức năng captcha đơn giản bằng ASP.Net với ngôn ngữ là C#. Bạn cần có các khái niệm cơ bản về ASP.Net và cách sử dụng phương thức đồ họa GDI+ trong C# để hiểu rõ được phương pháp này.

Đầu tiên bạn hãy tạo một WebSite ASP.Net, sử dụng sẵn trang Default.aspx để làm ví dụ này. Tạo các control giống như đoạn mã sau trong phần body của trang:

 


Giải thích công dụng các control:

– imgCaptcha: Image dùng để hiển thị hình ảnh captcha

– imbReload: ImageButton để thay đổi ảnh captcha

– txtCaptcha: TextBox để người dùng nhập chuỗi kí tự captcha

– btnSubmit: Button kiểm tra việc nhập liệu

– lblMessage: Label hiển thị thông báo sau khi người dùng nhấn nút Submit

Tiếp đến chúng ta cần tạo một phương thức để tạo ảnh captcha và hiển thị lên imgCaptcha, tôi đặt tên phương thức này là CreateCaptcha():
private void CreateCaptcha()

{

string[] fonts ={ “Arial Black”, “Lucida Sans Unicode”, “Comic Sans MS” };

const byte LENGTH = 5;

// chuỗi để lấy các kí tự sẽ sử dụng cho captcha

const string chars = “0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz”;

using (Bitmap bmp = new Bitmap(120, 30))

{

using (Graphics g = Graphics.FromImage(bmp))

{

// Tạo nền cho ảnh dạng sóng

HatchBrush brush = new HatchBrush(HatchStyle.Wave, Color.White,Color.Wheat);

g.FillRegion(brush,g.Clip);

// Lưu chuỗi captcha trong quá trình tạo

StringBuilder strCaptcha = new StringBuilder();

Random rand = new Random();

for (int i = 0; i < LENGTH; i++)

{

// Lấy kí tự ngẫu nhiên từ mảng chars

string str = chars[rand.Next(chars.Length)].ToString();

strCaptcha.Append(str);

// Tạo font với tên font ngẫu nhiên chọn từ mảng fonts

Font font = new Font(fonts[rand.Next(fonts.Length)], 12, FontStyle.Strikeout | FontStyle.Italic);

// Lấy kích thước của kí tự

SizeF size= g.MeasureString(str,font);

// Vẽ kí tự đó ra ảnh tại vị trí tăng dần theo i, vị trí top ngẫu nhiên

g.DrawString(str, font,

Brushes.Chocolate,i*size.Width+3, rand.Next(2,10));

font.Dispose();

}

// Lưu captcha vào session

Session["captcha"]=strCaptcha.ToString();

// Lưu ảnh vào thư mục captcha với tên ảnh dựa theo IP

string path = “Captcha/” + Request.UserHostAddress + “.gif”;

bmp.Save(Server.MapPath(“”) + “/” + path, ImageFormat.Gif);

imgCaptcha.ImageUrl = path;

}

}

}
(Đối tượng kiểu HatchBrush có rất nhiều kiểu vẽ cho bạn khá nhiều sự lựa chọn trong enum HatchStyle , bạn hãy thử tìm cho mình một style mà thích hợp để làm nền cho captcha.)

Sau đó hai viết tiếp mã lệnh cho các sự kiện sau:
protected void Page_Load(object sender, EventArgs e)

{

if (!IsPostBack)

CreateCaptcha();

}

protected void imbReLoad_Click(object sender, System.Web.UI.ImageClickEventArgs e)

{

CreateCaptcha();

}

protected void btnSubmit_Click(object sender, EventArgs e)

{

if (txtCaptcha.Text.Equals(Session["captcha"].ToString(), StringComparison.OrdinalIgnoreCase))

lblMessage.Text = “Chuỗi xác nhận chính xác”;

else

lblMessage.Text = “Vui lòng nhập đúng chuỗi xác nhận”;

}
Bây giờ hãy chạy thử và kiểm tra xem chức năng này có hoạt động đúng không, giao diện trang web như sau:
Minh hoa
Rất đơn giản phải không, tuy nhiên cách này có một số hạn chế như việc lưu tập tin ảnh quá nhiều vào thư mục captcha của server có thể gây lãng phí nhiều tài nguyên. Việc đọc ghi dữ liệu từ ổ cứng làm chậm tốc độ xử lý và các ảnh captcha vẫn được lưu lại trong thư mục nếu không xóa đi định kì.

Để giải quyết cho vấn đề này, chúng ta sẽ sử dụng kĩ thuật ghi trực tiếp ảnh ra đối tượng imgCaptcha thông qua luồng xuất đến máy khách.

Bây giờ bạn hãy tạo một trang aspx mới với tên Catpcha.aspx. Không cần quan tâm đến phần giao diện, bạn hãy copy đoạn mã trong phương thức CreateCaptcha() và đặt vào trong Page_Load, đồng thời sửa lại phần cuối của phương thức cho giống kết quả sau:
protected void Page_Load(object sender, EventArgs e)

{

string[] fonts ={ “Arial Black”, “Lucida Sans Unicode”, “Comic Sans MS” };

const byte LENGTH = 5;

// chuỗi để lấy các kí tự sẽ sử dụng cho captcha

const string chars = “0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz”;

using (Bitmap bmp = new Bitmap(120, 30))

{

using (Graphics g = Graphics.FromImage(bmp))

{

// Tạo nền cho ảnh dạng sóng

HatchBrush brush = new HatchBrush(HatchStyle.Wave, Color.White,Color.Wheat);

g.FillRegion(brush,g.Clip);

// Lưu chuỗi captcha trong quá trình tạo

StringBuilder strCaptcha = new StringBuilder();

Random rand = new Random();

for (int i = 0; i < LENGTH; i++)

{

// Lấy kí tự ngẫu nhiên từ mảng chars

string str = chars[rand.Next(chars.Length)].ToString();

strCaptcha.Append(str);

// Tạo font với tên font ngẫu nhiên chọn từ mảng fonts

Font font = new Font(fonts[rand.Next(fonts.Length)], 12, FontStyle.Strikeout | FontStyle.Italic);

// Lấy kích thước của kí tự

SizeF size= g.MeasureString(str,font);

// Vẽ kí tự đó ra ảnh tại vị trí tăng dần theo i, vị trí top ngẫu nhiên

g.DrawString(str, font,

Brushes.Chocolate,i*size.Width+3, rand.Next(2,10));

font.Dispose();

}

// Lưu captcha vào session

Session["captcha"]=strCaptcha.ToString();

// Ghi ảnh trực tiếp ra luồng xuất theo định dạng gif

Response.ContentType = “image/GIF”;

bmp.Save(Response.OutputStream, ImageFormat.Gif);

}

}

}
Sau đó hãy sửa lại phần body của trang Default.aspx

 


Có hai thay đổi nhỏ ở đoạn mã trên là thuộc tính ImageUrl của imgCaptcha được gán là trang Catpcha.aspx, và sự kiện OnClick của imbReLoad cũng được bỏ đi. Mỗi khi imbReLoad được nhấn, nó sẽ PostBack lại trang và do đó imgCaptcha lại lấy về ảnh mới.

Cuối cùng phần code-behind của trang Default.aspx chỉ còn lại:
protected void Page_Load(object sender, EventArgs e)

{

}

protected void btnSubmit_Click(object sender, EventArgs e)

{

if (txtCaptcha.Text.Equals(Session["captcha"].ToString(), StringComparison.OrdinalIgnoreCase))

lblMessage.Text = “Chuỗi xác nhận chính xác”;

else

lblMessage.Text = “Vui lòng nhập đúng chuỗi xác nhận”;

}
sưu tầm

Về tieuyeuit
Lập trình viên Asp.net Tôi chia sẻ một,bạn chia sẻ một và chúng ta có rất nhiều!

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s

%d bloggers like this: