做在线投票防止作弊的一些体会
前一陣子因為需要,做一個在線投票的程序,在程序發布以后,一直出現各種bug
一開始是用Cookies做驗證,客戶禁用Cookies作弊,后來采取記錄IP,客戶端用軟件速度換IP
后來還發現一個問題,就是投票按鈕可以重復提交,用戶按住投票按鈕不放,就可以一直刷票
最后,還是才用Cookies驗證的方法
思路是這樣的
首先在一個頁面產生一個驗證碼,把它記錄到一個Cookies里:Response.Cookies.Add(new HttpCookie("CheckCode", checkCode));
在投票按鈕事件出發后,首先判斷Response.Cookies["CheckCode"]是否==null,如果成立
則提示用戶需開啟Cookies才能投票,關閉投票小窗口
產生驗證碼的代碼如下:
CheckCode.aspx.cs
private string GenerateCheckCode()
{
int number;
char code;
string checkCode = String.Empty;
System.Random random = new Random();
for(int i=0; i<5; i++)
{
number = random.Next();
if(number % 2 == 0)
code = (char)('0' + (char)(number % 10));
else
code = (char)('A' + (char)(number % 26));
checkCode += code.ToString();
}
Response.Cookies.Add(new HttpCookie("CheckCode", checkCode));
return checkCode;
}
private void CreateCheckCodeImage(string checkCode)
{
if(checkCode == null || checkCode.Trim() == String.Empty)
return;
System.Drawing.Bitmap image = new System.Drawing.Bitmap((int)Math.Ceiling((checkCode.Length * 12.5)), 22);
Graphics g = Graphics.FromImage(image);
try
{
//生成隨機生成器
Random random = new Random();
//清空圖片背景色
g.Clear(Color.White);
//畫圖片的背景噪音線
for(int i=0; i<25; i++)
{
int x1 = random.Next(image.Width);
int x2 = random.Next(image.Width);
int y1 = random.Next(image.Height);
int y2 = random.Next(image.Height);
g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
}
Font font = new System.Drawing.Font("Arial", 12, (System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic));
System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2f, true);
g.DrawString(checkCode, font, brush, 2, 2);
//畫圖片的前景噪音點
for(int i=0; i<100; i++)
{
int x = random.Next(image.Width);
int y = random.Next(image.Height);
image.SetPixel(x, y, Color.FromArgb(random.Next()));
}
//畫圖片的邊框線
g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
Response.ClearContent();
Response.ContentType = "image/Gif";
Response.BinaryWrite(ms.ToArray());
}
finally
{
g.Dispose();
image.Dispose();
}
}
}
在Vote.aspx里引用上頁面所產生的驗證碼
在登錄頁面中使用“<IMG>” 這個 HTML 元素來顯示生成的驗證碼圖片:<IMG src="CheckCode.aspx">
投票按鈕事件處理
vote.aspx.cs
private void Button1_Click(object sender, System.EventArgs e)
{
if(Request.Cookies["CheckCode"] == null)
{
Response.Write("<script language=\"JavaScript\">alert('您的瀏覽器設置已被禁用 Cookies,您必須設置瀏覽器允許使用 Cookies 選項后才能投票!');window.close();</script>");
return;
}
Button1.Enabled = false;
UpdateVote();
}
private void UpdateVote()
{
if(String.Compare(Request.Cookies["CheckCode"].Value, txtValidate.Text, true) != 0)
{
Response.Write(HouseBasic.ScriptAlertMsg("驗證碼錯誤,請輸入正確的驗證碼。"));
return;
}
string vote = "," + Request.QueryString["id"];
if(Request.Cookies["Vote"] != null)
{
if(Request.Cookies["Vote"]["IP"] == Request.ServerVariables["REMOTE_ADDR"] && Request.Cookies["Vote"]["ID"].IndexOf(vote) >= 0)
{
Response.Write("<script language=\"JavaScript\">alert('您今天已經為本選手投了一票,不能再投了喲:');window.close();</script>");
Response.End();
}
vote += "," + Request.Cookies["Vote"]["ID"];
}
HttpCookie cookie = new HttpCookie("Vote");
cookie.Values.Add("IP", Request.ServerVariables["REMOTE_ADDR"]);
cookie.Values.Add("ID", vote);
cookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(cookie);
//投票處理
}
現在還剩下防止Button按鈕重復提交了
在網上搜索了一個防止重復提交的js方法
js.js
function _doPostBack(){};
if(typeof("__doPostBack")=="function")
{
_doPostBack=__doPostBack;
__doPostBack=_doPostBackNew;
}
document.attachEvent("onmousemove",_onmousemove);
var _isPosting=false;
var _divMask=null;
function _onmousemove()
{
if(_divMask)
with(_divMask.runtimeStyle)
{
left=event.clientX+document.body.scrollLeft-4;
top=event.clientY+document.body.scrollTop-4;
}
}
function _makeMask()
{
var div=document.createElement("DIV");
with(div.runtimeStyle)
{
position="absolute";
zIndex=999999;
fontSize="1px";
left=event.clientX+document.body.scrollLeft-4;
top=event.clientY+document.body.scrollTop-4;
width="8px";
height="8px";
cursor="wait";
backgroundColor="gray";
filter="alpha(opacity=10)";
}
try
{
document.body.insertAdjacentElement("BeforeEnd",div);
div.onblur=new Function("this.focus()");
div.focus();
}
catch(x){}
if(_divMask)_divMask.removeNode(true);
_divMask=div;
}
function _doPostBackNew(sender,args)
{
if(_isPosting)
return event.returnValue=!(event.cancelBubble=true);
status="正在更新頁面...";
_doPostBack(sender,args);
_isPosting=true;
_makeMask();
}
function _onformsubmit()
{
if(_isPosting)
return event.returnValue=!(event.cancelBubble=true);
_isPosting=true;
_makeMask();
}
new function _attachForms()
{
with(new Enumerator(document.forms))
for(;!atEnd();moveNext())
{
item().attachEvent("onsubmit",_onformsubmit);
var div=document.createElement("div");
div.runtimeStyle.width="0px";
div.runtimeStyle.hight="0px";
div.runtimeStyle.overflow="hidden";
div.runtimeStyle.position="absolute";
item(0).insertAdjacentElement("afterbegin",div);
div.innerHTML="<INPUT TYPE=Submit name='webformpatchsubmitelement' onclick='return event.returnValue=false' id='webformpatchsubmitelement' value='webformpatchsubmitelement'/>";
}
}
把這個作為 <-script src=js.js-><-/script-> 的形式Render到每個頁面中就可以了。|
如果有PageBase,則在Init的時候用RegisterClientScriptBlock放上去更好。
如:this.RegisterStartupScript("JS","<script src=\"js.js\" type=\"text/javascript\"></script>");
我的這個投票基本上處理,能防止一些常見的作弊方法,歡迎大家提出不足之處
和漏洞
總結
以上是生活随笔為你收集整理的做在线投票防止作弊的一些体会的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle中imp命令详解
- 下一篇: windows添加PDF虚拟打印机