投票系统-如何限制单位时间内投票次数
博客分类: 软件设计
限制对于防止倒票没有什么绝对的好方法,尤其是用户不需注册的情况下的投票,我们来看看有那些方法来防止倒票:
1.Session 采用Session对象防止重复投票好像还不错,如果您利用单一浏览器进行测试,确实可以证明Session具有防止重复投票的功能,实际上开启另一个浏览器,Session变了,那么又可以投票了.为什么呢?因为每一个执行中的浏览器对应一个Session对象,虽然我们可以设置第一个浏览器的Session值,但是第二
个.第三个.....无法设置了..
2.Cookie 一般利用Cookie进行设置,主要是设置Cookie的失效时间,也就是在这段时间内,这台电脑的信息被Cookie保存,你可以做允许的事情,这样我们可以利用其进行投票,比如说登录的时候将Client的IP地址赋值给Cookie,Cookies("Value").Expires="12/31/2999";用户登录的时候,我们检查Cookie是否有值,来决
定他是否有权限进行投票.这种方法比Session应该好多了,重启,开启多个浏览器都被Cookie左右,但是致命的一项是Cookie是可以清除的,这样我们的设置又轻易的被破解了.
3.IP+数据库 这是目前还算有效但是不是绝对有效的方法,下面的示例将记录我做的教师测评的限制IP的源码.用户登录的时候,取得Client端的IP,并且与系统数据库存储的IP比较(系统存储的数据可以按照时间的
降序排列,这样如果有重复IP,我们只比较最上面的那条就可以了,具体看代码!):如果相同的话,再次比较时间,如果两者时间差超过半小时则可以投票,否则警告信息:一台电脑半小时内
只能投票一次;如果不相同的话,就是说明这个IP没有投票过,那么可以进行投票,同时更新IP和时间纪录!这种方法也有一致命的漏洞---动态IP地址,比如ADSL还有其它的动态变化的IP等等,这样也就失去作用
了(由于我们学校是静态IP,所以我这样做啦,o(∩_∩)o...哈哈).
4.IP+Cookie 这种方法又多了一层保障,但是对于动态IP地址+删除Cookie的组合来说还是可以破解的.
5.Mac 网卡的物理地址在世界唯一,我们可以通过网卡的Mac地址(物理地址)来进行锁定电脑,这方法看起来不错,但是很多软件都能制造伪Mac地址....
6.就是用户注册ID投票,这样限制一个ID只能投票一次或者单位时间内只能投1次效果是非常好的,但是一个人也可以注册很多用户ID啊!!所以上述6中方法没有一种是100%有效的方法,大家根据自己所需,按照自己的要求选择,所谓防君子,不防
博客分类: 软件设计
限制对于防止倒票没有什么绝对的好方法,尤其是用户不需注册的情况下的投票,我们来看看有那些方法来防止倒票:
1.Session 采用Session对象防止重复投票好像还不错,如果您利用单一浏览器进行测试,确实可以证明Session具有防止重复投票的功能,实际上开启另一个浏览器,Session变了,那么又可以投票了.为什么呢?因为每一个执行中的浏览器对应一个Session对象,虽然我们可以设置第一个浏览器的Session值,但是第二
个.第三个.....无法设置了..
2.Cookie 一般利用Cookie进行设置,主要是设置Cookie的失效时间,也就是在这段时间内,这台电脑的信息被Cookie保存,你可以做允许的事情,这样我们可以利用其进行投票,比如说登录的时候将Client的IP地址赋值给Cookie,Cookies("Value").Expires="12/31/2999";用户登录的时候,我们检查Cookie是否有值,来决
定他是否有权限进行投票.这种方法比Session应该好多了,重启,开启多个浏览器都被Cookie左右,但是致命的一项是Cookie是可以清除的,这样我们的设置又轻易的被破解了.
3.IP+数据库 这是目前还算有效但是不是绝对有效的方法,下面的示例将记录我做的教师测评的限制IP的源码.用户登录的时候,取得Client端的IP,并且与系统数据库存储的IP比较(系统存储的数据可以按照时间的
降序排列,这样如果有重复IP,我们只比较最上面的那条就可以了,具体看代码!):如果相同的话,再次比较时间,如果两者时间差超过半小时则可以投票,否则警告信息:一台电脑半小时内
只能投票一次;如果不相同的话,就是说明这个IP没有投票过,那么可以进行投票,同时更新IP和时间纪录!这种方法也有一致命的漏洞---动态IP地址,比如ADSL还有其它的动态变化的IP等等,这样也就失去作用
了(由于我们学校是静态IP,所以我这样做啦,o(∩_∩)o...哈哈).
4.IP+Cookie 这种方法又多了一层保障,但是对于动态IP地址+删除Cookie的组合来说还是可以破解的.
5.Mac 网卡的物理地址在世界唯一,我们可以通过网卡的Mac地址(物理地址)来进行锁定电脑,这方法看起来不错,但是很多软件都能制造伪Mac地址....
6.就是用户注册ID投票,这样限制一个ID只能投票一次或者单位时间内只能投1次效果是非常好的,但是一个人也可以注册很多用户ID啊!!所以上述6中方法没有一种是100%有效的方法,大家根据自己所需,按照自己的要求选择,所谓防君子,不防
小人嘛o(∩_∩)o...哈哈
接下来是常用功能代码的实现:
</pre><pre name="code" class="cpp">功能:同一用户帐号投票完就不能继续投票(我这里是利用数据库的一个字段,解决session的一些弊端而且这个字段还能用于其他地方)
功能:cookies记录ip地址,每次检查先cookies遍历一遍<pre name="code" class="cpp">(可以设置时间隔多久就可以继续投)
新手注意下面代码的"///注释部分即可" 切勿全部复制然后问我为什么报错= =
package servlets;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import dao.impl.VoteDaoImpl;
import dao.impl.VoteInfoDaoImpl;
import service.IVoteService;
import values.ApplyValue;
import values.VoteInfoValue;
import vote.dao.IVoteDao;
import vote.dao.VoteInfoDao;
import vote.show.VoteInfo;
import vote.utils.ConvertUtil;
public class VoteServlet extends HttpServlet {
/**
* Destruction of the servlet. <br>
*/
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//PrintWriter out = response.getWriter();
String method = request.getParameter("method");
System.out.println("method="+method);
//response.setCharacterEncoding("utf-8");
HttpSession session = request.getSession();
String userid=(String) session.getAttribute("userid");
System.out.println("userid="+userid);
PrintWriter out = response.getWriter();
ConvertUtil cutils = new ConvertUtil();
List listVote = new ArrayList();
//业务处理层
//IVoteService ivote = new VoteServiceImpl();
IVoteDao ivote = new VoteDaoImpl();
VoteInfoDao vid=new VoteInfoDaoImpl();
String tourl = "";
// 判断请求是否为投票操作。
// if ("addvote".equals(method)) {
// String vname = request.getParameter("vname");
// ivote.insertVote(vname);
// tourl = "vote.do?method=votemanage";
// } else
if ("voting".equals(method)) {
// if (session.getAttribute("times") == null) {
//用方法类将取得的String变为int
//ServletContext application=session.getServletContext();
//String usernam=(String) application.getAttribute("usernam");
//String userid=request.getParameter("id");
//System.out.println("userid="+userid);
boolean temp=false;
temp=vid.searchName(userid);
String IP = request.getRemoteHost();
System.out.println(IP);
Cookie[] cookies = request.getCookies();/取得所有cookies
boolean flag = true;
for (int i = 0; i < cookies.length; i++) {
if (IP.equals(cookies[i].getValue())) {
<span style="white-space:pre"> </span>//ip验证
flag = false;
break;
}}
System.out.println("flag="+flag);
System.out.println("temp="+temp);
if(flag&&(!temp)){ //双重保险
System.out.println("检测用的");
String voteids1[] = request.getParameterValues("voteid1"); //得到被投票人的id
//String voteids2[] = request.getParameterValues("voteid2");
//解决空指针异常问题
if(voteids1==null) {
String mess = "<script>alert('您没有选择任何投票项目,请返回后重新投票谢谢!');</script>";
request.setAttribute("mess", mess);
tourl = "/GetDBtoShow?mymethon=tovote";
request.getRequestDispatcher(tourl).forward(request, response);
return;
}
//通过这里控制能得到的投票个数
System.out.println("voteid="+voteids1[0]);
if (voteids1.length <=2&&voteids1.length>0) {
System.out.println("获得的长度>0");
ivote.updataVcount(voteids1);
vid.insertData(userid, voteids1);
//session.setAttribute("times", "do");
//mess作为js
String mess = "<script>alert('投票成功,谢谢支持!!');</script>";
Cookie cookie = new Cookie("IP", IP); /存ip
// cookie.setMaxAge(30);//存放30天够多的了= =
cookie.setMaxAge(60*60*24*30);//存放30天够多的了= =
response.addCookie(cookie);//回写到浏览器
//application.setAttribute("usernam", userid);
request.setAttribute("mess", mess);
}
else if(voteids1.length>2){
String mess = "<script>alert('选项不能多于两个=。=');</script>";
request.setAttribute("mess", mess);
}
}
else {
String mess = "<script>alert('您已经投过票,请不要重复投票!');</script>";
request.setAttribute("mess", mess);
}
tourl = "/GetDBtoShow?mymethon=tovote";
} else if ("view".equals(method)) {
//显示第一个页面
int totalnum1 = ivote.totalVote_1();//得到总票数
// int totalnum2 = ivote.totalVote_23();//得到总票数
List list1 = ivote.getVoteList1();//得到满足isok的人
// List list2 = ivote.getVoteList2_3();//得到满足isok的人
List voteList1 = new ArrayList();
// List voteList2 = new ArrayList();
if (list1 != null) {
for (int i = 0; i < list1.size(); i++) {
if(totalnum1==0){totalnum1=1;}
ApplyValue vote = (ApplyValue) list1.get(i);//得到第 i个对象
double ii = (double) vote.getVcount() / totalnum1 * 100;
NumberFormat formatter = NumberFormat.getNumberInstance();
double bfb=(double) vote.getVcount() / totalnum1;
formatter.setMaximumFractionDigits(2);
String vs = formatter.format(ii) + "%";//投票占百分比
int width = vote.getVcount() * 100 / totalnum1;
VoteInfo voteinfo = new VoteInfo();
voteinfo.setNumber(i + 1);
//voteinfo.setVotename(vote.getA_name());
voteinfo.setVotename(vote.getA_name());
voteinfo.setCount(vote.getVcount());
voteinfo.setBfb(bfb);//double 百分比
voteinfo.setVs(vs);//投票占百分比
voteinfo.setWidth(width);
voteList1.add(voteinfo);
}
request.setAttribute("voteList1", voteList1);
//tourl = "/GetDBtoShow?mymethon=toview";
//tourl = "/WEB-INF/view.jsp";
}
// if (list2 != null) {
// for (int i = 0; i < list2.size(); i++) {
// ApplyValue vote = (ApplyValue) list2.get(i);//得到第 i个对象
// double ii = (double) vote.getVcount() / totalnum2 * 100;
// NumberFormat formatter = NumberFormat.getNumberInstance();
// formatter.setMaximumFractionDigits(2);
// String vs = formatter.format(ii) + "%";//投票占百分比
// int width = vote.getVcount() * 100 / totalnum2;
// VoteInfo voteinfo = new VoteInfo();
// voteinfo.setNumber(i + 1);
// //voteinfo.setVotename(vote.getA_name());
// voteinfo.setVotename(vote.getA_name());
// voteinfo.setCount(vote.getVcount());
// voteinfo.setVs(vs);//投票占百分比
// voteinfo.setWidth(width);
// voteList2.add(voteinfo);
// }
// request.setAttribute("voteList2", voteList2);
// //tourl = "/GetDBtoShow?mymethon=toview";
//
// }
//显示第二个页面
List voteinfolist=vid.getVoteList();
List voteinL = new ArrayList();
if (voteinfolist != null) {
for (int i = 0; i < voteinfolist.size(); i++) {
VoteInfoValue votevalue=(VoteInfoValue) voteinfolist.get(i);
voteinL.add(votevalue);
}
request.setAttribute("voteinL", voteinL);
}
System.out.println("实现了第二页面的初始化");
tourl = "/WEB-INF/NewView.jsp";
}
else if ("showuservote".equals(method)) {
List voteinfolist=vid.getVoteList();
List voteinL = new ArrayList();
if (voteinfolist != null) {
for (int i = 0; i < voteinfolist.size(); i++) {
VoteInfoValue votevalue=(VoteInfoValue) voteinfolist.get(i);
voteinL.add(votevalue);
}
request.setAttribute("voteinL", voteinL);
}
System.out.println("实现了第二页面的初始化");
tourl = "/WEB-INF/UserVoteInfo.jsp";
}
else if ("votemanage".equals(method)) {
List list = ivote.getVoteList();
request.setAttribute("votelist", list);
tourl = "mainvote.jsp";
} else if ("edit".equals(method)) {
ApplyValue vote = new ApplyValue();
int id = cutils.strToInt(request.getParameter("id"));
String vname = request.getParameter("vname");
int vcount = cutils.strToInt(request.getParameter("vcount"));
vote.setA_id(id);
vote.setA_name(vname);
vote.setVcount(vcount);
if (ivote.updataVoteByVote(vote)) {
request.setAttribute("mess", "编辑成功");
} else {
request.setAttribute("mess", "编辑失败");
}
tourl = "result.jsp";
}
// else if ("toedit".equals(method)) {
// int tmpid = cutils.strToInt(request.getParameter("id"));
// ApplyValue vote = ivote.getVoteById(tmpid);
// request.setAttribute("vote", vote);
// tourl = "voteEdit.jsp";
// }
else if ("delete".equals(method)) {
int id = cutils.strToInt(request.getParameter("id"));
ivote.delete(id);
tourl = "vote.do?method=votemanage";
} else {
tourl = "vote.do?method=votemanage";
}
request.getRequestDispatcher(tourl).forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
/**
* Initialization of the servlet. <br>
*
* @throws ServletException if an error occurs
*/
public void init() throws ServletException {
// Put your code here
}
}