你是怎样进行防重提交设计的?

点击上方Java之间”,选择“置顶或者星标”

你关注的就是我关心的!

你是怎样进行防重提交设计的?

作者:Guooo

微信公众号:歪脖贰点零

为什么需要防范重复提交呢?举个最直接的栗子:你在商城里买了7888元的iphone x,付款后页面卡顿导致你重复点击了付款按钮,这时候如果后端不加重复交易验证的话,相当于付款15766元买了Iphone x手机,划算吧?

不单是互金系统交易时会生产此问题,凡涉及表单提交都会遇到,这里以某互金系统为例说明交易防重的过程设计。下图是交易防重设计的示图:

你是怎样进行防重提交设计的?

这个过程相信大家都不陌生,生活中随处可见。开封菜的甜品站,先付款,再给小票,拿着小票到取餐口拿甜品,交易完成后,小票撕毁。这就是一个典型的防止重复取餐的例子。

回到上图,来深入了解一下这个过程:

1、在进入到需要防重交易的表单页面之前,请求后端生成token的服务,生成token并存储在后端,与该用户的请求绑定,便于后期在交易验证时与之比对,token返回到交易页面。

2、携带token提交表单,在进入真正交易之前,做token验证(比如使用AOP),如果存在,则token正常,比对成功后销毁进入正常的交易功能。如果不存在,则证明token已经被销毁,为重复提交请求。

以上步骤可以看出token的关键性,若token获取失败,那么交易将无法完成,所以需要保证token服务的高可用性。

以上过程针对一个交易是完全没有问题的,但若涉及两个以上的关键交易提交时,就会出现后请求的交易获取的token替换首次交易获取的token,那么在首次交易提交时,会出现token找不到的情况,导致交易失败。由此引出另外两个关键的问题点:

token的数量以及token的销毁机制。 数量决定了能同时发起交易的数量,所以token的数量最好能够覆盖所有关键交易同时发起来的数量。token的销毁决定了使用token的正常顺序。

基于上面流程,我们再改造一下生成token的模块。

你是怎样进行防重提交设计的?

关键示例代码:

你是怎样进行防重提交设计的?

生成token方法

你是怎样进行防重提交设计的?

你是怎样进行防重提交设计的?

交易校验,主要由拦截器完成。

你是怎样进行防重提交设计的?

一般的解决方案是在前端由JS控制提交表单按钮,提交后置灰,禁止第二次提交。但此方法也只针对小白用户有效,防范机制也不是很彻底,比如直接调用请求而非通过页面表单进行,比如JS校验代码清除等,可以绕过JS的置灰功能进行二次提交。

采用前端JS置灰防止重复提交请求,再加上后端token验证,可以更有效的防止关键交易的重复提交。

原文链接:

https://mp.weixin.qq.com/s/pIUPiOXfUX73RCuu7zoppg

你是怎样进行防重提交设计的?

最近热文阅读:

1、Java 8中Stream API集合操作的奇技淫巧!

2、Maven 的这 7 个问题你思考过没有?

3、最易懂的数据库异地多活方案

4、分布式事务常见的5种解决方案

5、为什么你的Intellij没别人的好用?

6、秒杀系统流量削峰这事应该怎么做?

7、程序员进新公司 团队都用java8函数式语法 开始内心是拒绝的

8、Class.forName 和 ClassLoader 到底有什么区别?

你是怎样进行防重提交设计的?

关注公众号,你想要的Java都在这里