服务器端防止重复提交的一个实现

来源:互联网 发布:华傲数据技术有限公司 编辑:程序博客网 时间:2024/05/19 04:02

由于web服务器要同时处理大量的http请求,所以用户的某个提交会得不到及时的相应。

这样用户会有意无意的重复点击提交,如果没有很好的措施来防止这种情况。会对系统的安全性带来隐患。

常用的防止重复提交的方法有两种:

1.通过javascript代码在客户端浏览器进行处理。

2.在服务器端进行处理。

 

其中第二种的安全性更高。

 

以下是一个在服务器端进行的防止用户重复提交的一个实现。

 

public class TokenProcessor {    private static final String TOKEN_KEY="token";    private static TokenProcessor instance=new TokenProcessor();    public static TokenProcessor getInstance(){        return instance;    }    private long last;    public synchronized boolean isTokenValid(HttpServletRequest request){        HttpSession session=request.getSession(false);        if(null==session){            return false;        }        String attributeToken=(String)session.getAttribute(TOKEN_KEY);        if(attributeToken==null){            return false;        }        resetToken(request);        String parameterToken=(String)request.getParameter(TOKEN_KEY);        if(null==parameterToken){            return false;        }        return attributeToken.equals(parameterToken);    }        public synchronized void resetToken(HttpServletRequest request){            HttpSession session=request.getSession(false);        if(null==session){            return;        }        session.removeAttribute(TOKEN_KEY);    }          public synchronized void saveToken(HttpServletRequest request){         HttpSession session=request.getSession(false);         String token=generateToken(request);         if(token!=null){             session.setAttribute(TOKEN_KEY, token);         }                          }    public String generateToken(HttpServletRequest request) {        HttpSession session=request.getSession(false);                byte[] id=session.getId().getBytes();        long current=System.currentTimeMillis();        if(current==last){            current++;        }        last=current;                byte[] now=new Long(current).toString().getBytes();        try {            MessageDigest md=MessageDigest.getInstance("MD5");            md.update(id);            md.update(now);            return toHex(md.digest());        } catch (NoSuchAlgorithmException ex) {            return null;        }            }    private String toHex(byte[] buffer) {       StringBuffer sb=new StringBuffer(buffer.length*2);              for(int i=0;i<buffer.length;i++){                    sb.append(Character.forDigit((buffer[i]&0xf0)>>4, 16));            sb.append(Character.forDigit(buffer[i]&0x0f, 16));                    }         return sb.toString();               }        public synchronized String getToken(HttpServletRequest request){            HttpSession session=request.getSession(false);        if(session==null){                   return null;        }        String token=(String) session.getAttribute(TOKEN_KEY);        if(token==null){                    token=generateToken(request);            if(token!=null){                           session.setAttribute(TOKEN_KEY, token);               return token;            }else{                return null;                        }        }        return token;            }}

 

 

实现原理为:

当用户提交时,参数中会有一个token。在服务器端进行处理的时候,会验证该token。验证成功,则处理。

验证不成功,可以提示用户不能重复提交。

代码比较简单,不做过多说明。

0 0
原创粉丝点击