Spring Boot实现URL直接访问跳转及按钮防重复点击失效问题咨询
Spring Boot需求解决方案
一、重复提交漏洞修复
1. 接口请求方式修正
写操作接口禁止使用GET请求,GET是幂等性查询方法,地址栏输入URL默认发起GET请求,将原接口的请求方式改为仅支持POST,从根源避免地址栏直接访问触发业务逻辑:
// 原接口修改为仅支持POST @PostMapping("/Balnce_add") public ModelAndView GoesUp(@AuthenticationPrincipal CustomUserDetails currentuser) throws IOException { if (isAuthenticated()) { // 后续新增防重校验逻辑 int x=currentuser.getBalance() +10; currentuser.setBalance(x); repo.setUserInfoById(x,currentuser.getId()); repoofdata.setDataInfoById(x,currentuser.getId()); System.out.println(currentuser.getName()+" (new balance) ==> " +currentuser.getBalance()); return new ModelAndView("redirect:"+"/game1"); } return new ModelAndView("redirect:"+"/signin"); }
2. 后端新增防重校验
前端按钮禁用仅能拦截普通用户操作,后端必须加校验逻辑,可选两种实现方案:
- 轻量方案:以用户ID+接口路径作为唯一标识,存入缓存并设置10秒过期时间,请求进入时先校验标识是否存在,存在则直接拒绝请求,不存在则写入标识再执行业务逻辑,与前端禁用周期保持一致。
- 高可靠方案:页面加载时后端生成唯一防重Token,存入缓存同时传到前端,请求接口时必须携带该Token,后端校验Token存在才执行逻辑,执行后立即删除Token,保证单次请求仅能执行一次。
3. 前端请求适配
原按钮绑定的up方法改为发起POST请求,示例逻辑如下:
function up() { const btn = document.getElementById('upside') btn.disabled = true // 发起POST请求 fetch('/Balnce_add', { method: 'POST' }).then(() => { window.location.href = '/game1' }).finally(() => { // 10秒后恢复按钮可用 setTimeout(() => btn.disabled = false, 10000) }) }
二、地址栏输入URL自动跳转实现
原接口仅支持POST后,用户在地址栏输入/Balnce_add会触发GET请求,默认返回405错误,单独新增GET请求映射处理跳转逻辑即可:
// 处理GET请求直接跳转对应页面 @GetMapping("/Balnce_add") public ModelAndView handleBalanceAddGetAccess() { return new ModelAndView("redirect:/game1"); }
如果需要其他指定URL的跳转逻辑,按照同样方式新增对应GET映射,返回对应重定向地址即可。
额外优化建议
涉及用户余额这类核心数据修改,建议数据库层新增乐观锁(如version字段),更新数据时携带版本号校验,避免并发请求导致的数据不一致问题。
内容的提问来源于stack exchange,提问作者LEGENDRYzZzZ
相关产品推荐
相关产品推荐

