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

1 篇文章 0 订阅
0 篇文章 0 订阅

由于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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值