最近在做项目遇到表单重复提交的问题,前后端完全分离的项目,采用的的是基于Token注解+拦截器的方式解决的,大概的思路是:
1、前端先请求后台一个方法,后台生成token并保存在session中,然后再将token返回给前端。
2、前端填充表单数据 带上token一并提交给后台
3、后台比对session中的token和前台传过来的token,若一致则成功提交,然后后台销毁session中的token,若不一致则提示重复提交表单
此方法能够拦截住普通的重复提交问题,但是如果用户恶意伪造token依旧能重复提交,恶意伪造的大概流程是这样的:
1、前端正常请求一个页面(A页面),后台生成token保存在session中,并将token返回给前端(A页面)
2、前端带上A页面接收到的token能成功提交表单,提交后,此时session中token已经被销毁
3、用户通过浏览器回退到已经提交的表单页面(A页面),企图再次提交表单(此时如果再次提交会被拦截,因为session中的token已经被销毁)
4、如果用户重新打开一个窗口,进入一个表单页面(B页面),此时后台会重新生成一份token保存在session中,并返回给前端页面
5、如果用户将A页面(已提交的表单)的token改为B页面接收到的最新的有效token,并一起提交,此时验证依旧能通过,但是系统中产生了脏数据。
本人测试的token对于同一个用户是公共的变量,所有的表单共用token,有没有基于表单的,进入一个表单后会生成一个唯一的token,这样再也伪造不了了,不知道各位有什么更好的解决方案