想知道如何正确地保证表单提交的幂等性吗?(三)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 哈喽,大家好,我是指北君。关于表单的提交相信作为一个后端开发接触过不少,本文将介绍如何解决表单重复提交的问题。

②、表单页面增加隐藏域存储tokenId102.png103.png

③、提交表单,后端进行是否重复判断

104.png105.png

106.gif

上面主要是利用一次回话中session域存储的数据是保持不变的,而request域只能保存一次请求的数据。

注意:页面首先要通过 servlet 进行跳转过去,不能直接访问jsp页面。先在 servlet 中生成一个 tokenId,然后将tokenId存入到session域中,在转发到jsp表单页面,在表单页面中,通过隐藏域存放生成的tokenId,然后点击提交按钮,会将隐藏域的tokenId 也一起提交到后端。后端首先判断表单中的tokenId值,以及和session域中的tokenId 值进行对比,表单中的tokenId为null,则说明是直接访问的jsp页面,session域中的tokenId 为null,则说明不是第一次提交,因为第一次提交成功之后会清空session域中的tokenId。都不为null,且两者不相等,则说明可能是伪造的tokenId;不为null,且相等,则说明是第一次提交。

这里要注意销毁session域中的tokenId时机,是在判断完是否重复提交的方法中最后就销毁了,这样可以防止还没销毁session域中的tokenId,客户端的请求又来了。

5、session共享问题

通过上面前后端的解决表单重复提交的问题,我们看似解决了,其实不然,对于各种分布式项目,为了解决高并发的问题,我们会将前端请求通过 nginx 负载到多个tomcat服务器,如下:


107.jpg

这里会存在这样一个问题:

首先通过 tomcat1 将请求跳转到表单页面,这时候tokenId 是存放在tomcat1 session域中,然后点击提交按钮,nginx 可能会将我们的请求分发到 tomcat2 上,而tomcat2 的session 域中是不存在 tokenId 的,这时候我们提交不了表单。

这也是session共享问题。也就是说我们必须找到一个存放 tokenId 的公共介质,无论是哪个服务器去处理请求,都是从公共介质中获取 tokenId,那么当然不会存在tokenId 不一致的问题。

解决办法:

①、利用数据库同步:也就说将 tokenId 存放在数据库中,每次获取的时候从数据库中查询,这能解决,但是对数据的访问压力增大,不太合适。

②、利用 cookie 同步:因为 cookie 是存在本地客户端的,第一次请求我们将tokenId 存放在cookie中,然后从cookie进行是否重复提交校验,这也能解决问题。但是cookie 存在安全性问题,而且每次http请求都要带上参数也增加了带宽消耗。

③、利用 Redis 同步:这是最好的一种办法,Redis是一个高性能缓存框架,我们将 tokenId 存放在Redis中,获取也从Redis中获取,而且Redis性能极佳。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
SQL 缓存 NoSQL
接口的幂等性设计和防重保证,详细分析幂等性的几种实现方法
本篇文章详细说明了幂等性,解释了什么是幂等性,幂等性的使用场景,讨论了幂等和防重的概念。分析了幂等性的情况以及如何设计幂等性服务。阐述了幂等性实现防重的几种策略,包括乐关锁,防重表,分布式锁,token令牌以及支付缓冲区。
5087 0
接口的幂等性设计和防重保证,详细分析幂等性的几种实现方法
|
3月前
|
数据库 索引
常见保持请求幂等的方式
常见保持请求幂等的方式
21 0
|
4月前
|
消息中间件 关系型数据库 MySQL
如何保证消息幂等
如何保证消息幂等
25 0
|
9月前
|
SQL NoSQL Java
【项目场景】如何保证接口的幂等性?
【项目场景】如何保证接口的幂等性?
330 0
|
9月前
|
缓存 NoSQL JavaScript
8 种方案解决重复提交问题,还怕没有适合你的?
8 种方案解决重复提交问题,还怕没有适合你的?
|
11月前
|
前端开发 NoSQL 数据库
幂等性与防重的区别
自己的一点小理解
384 0
|
前端开发 NoSQL Java
什么是接口幂等性?为什么会产生接口幂等性问题?如何保证接口幂等性?
什么是接口幂等性?为什么会产生接口幂等性问题?如何保证接口幂等性?
255 0
什么是接口幂等性?为什么会产生接口幂等性问题?如何保证接口幂等性?
|
前端开发 NoSQL Java
如何保证接口幂等性?一口气说了12种方法!
幂等性原本是数学上的概念,用在接口上就可以理解为:**同一个接口,多次发出同一个请求,必须保证操作只执行一次**。调用接口发生异常并且重复尝试时,总是会造成系统所无法承受的损失,所以必须阻止这种现象的发生。
474 0
|
缓存 弹性计算 负载均衡
11. 分布式系统接口,如何避免表单的重复提交?
11. 分布式系统接口,如何避免表单的重复提交?
183 0
|
消息中间件 缓存 NoSQL
详细讲解服务幂等性设计
在日常工作中的一些技术设计方案评审会上,经常会有提到注意服务接口的幂等性问题,最近就有个同学就跑到跟前问我,幂等性到底是个啥?
详细讲解服务幂等性设计