DoubleSubmit

(1)问题描述

     一般网页按refreshreload更新网页时,browser会重复执行上一次getpost动作,如果没有检查这样的行为,则Double submit在重要应用会有问题(可能会下多次订单)。

(2)解决方法

     利用token比对方式,当正常的submit动作时,client送到controllertokensession中的token比对相同,则视为正常的submit

     若按下refresh送到controllertoken会是上次的token,所以与session中的token不同,则视为refresh动作,此时可以显示警告信息。

(3)token同步令牌:

     服务器端在处理到达的request之前,会将request中的token值与保存在当前用户session中的令牌值比较,看是否匹配。匹配则为正常的submit。在处理完request之后,且在response发送给客户端之前,会产生一个新的token,该token除了传给客户端外,也会将用户session中旧的token替换掉。这样,如果用户回退到刚才的提交页面并再次提交,则客户端传过来的token与服务器端不一致,所以避免重复提交。

(4)示例

       

        按下“新增”会增加一条,并返回原页面;如果按下refresh会出现选择框,选择“重试”,则浏览器会重新执行post动作,若没有检查,则会再新增一条记录

<1>   

CannotDoubleSubmitCommand cmd=(CannotDoubleSubmitCommand)command;
	String action=cmd.getAction();
	Long requestToken=cmd.getToken();//取出页面回传回来的Token
	HttpSession session=request.getSession();
	Long sessionToken=(Long)session.getAttribute(“TokenKey”);//取出session中的token
		if(“Add”.equals(action)){
	if(isTokenValid(requestToken,request)){//比较2个token是否相同
	   List<TaskDO> taskes=cmd.getTaskes();
	   TaskDO task=createTask(taskes.size()+1);
	   taskes.add(task);
	   Long nextToken=nextToken();//取到下一个token
	   session.setAttribute(“TokenKey”,nextToken);
	   cmd.setToken(nextToken);
    }else{
	   errors.reject(null,“Invalid token, not allow to refresh page”);
	   Long next Token=nextToken();
	   //必须重新设定token,否则client无法再submit.
	   session.setAttribute(“TokenKey”,nextToken);
	   cmd.setToken(nextToken);
    }
}


<2>

protected boolean isTokenValid(Long requestToken,HttpServletRequest request){
	Long sessionToken=doGetSessionToken(request);
	if(requestToken==null){
	  throw new RuntimeException(“Missing token in request”);
    }
    if(sessionToken==null){
 	  throw new RuntimeException(“Missing token in session”);
    }
    if(sessionToken.equals(requestToken)){
	  return true;
    }
     return false;
}


<3>

protected Long nextToken(){
	long seed=System.currentTimeMillis();
	Random r=new Random();
	r.setSeed(seed);
	return r.nextLong();
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值