他说的是如果一个人不小心点击两次,生成不同请求如何保证幂等?两次不同请求代表 token 不同或者前端发送的随机数不同,那如何防止??
1
676529483 2020-08-27 17:10:25 +08:00
如果两次点击是误操作,那用一些全局唯一的标识就可以了,比如 uuid 之类的,后端来判断是不是同一次页面的;
如果是想要防止业务点击多次,那就要业务 参数来幂等了,比如订单号 |
2
lyog 2020-08-27 17:12:34 +08:00 via iPhone
如果是我,我会用个分布式锁,然后再加插前查询
|
3
coderxy 2020-08-27 17:13:49 +08:00
1.首先看什么样的接口,如果是 get 请求啥的天然幂等,不需要另外处理
2.一般这种场景,前端会设计冷却锁。即一个按钮点击后除非请求结果返回或者过了多长时间,才会再次发起请求 3.如果前端无法控制,那么可以在接口设计上考虑。比如如果是创建一个资源,可以在后端加上并发锁,一个用户只能有一个创建动作在执行,其它请求排队。 总的来说方案很多,还是要根据实际场景设计。 |
4
takemeaway 2020-08-27 17:14:01 +08:00
先前端限制不能点两次,方法很多。
后端再用唯一值和事务限制一下就行了。 |
5
lidlesseye11 2020-08-27 17:24:32 +08:00 4
个人觉得幂等性是业务设计问题,不是技术问题吧。。
两次请求都不同了凭啥要幂等? |
6
garlics 2020-08-27 17:27:31 +08:00
带上 csrf token ?
|
7
ylsc633 2020-08-27 17:31:12 +08:00 1
1. web 常见的就是 csrf token
2. 前端按钮限制仅点击一次 3. 每个提交地址带个随机参数,用完即废 4. 数据做幂等插入 5.etc. |
8
lipcao 2020-08-27 17:31:24 +08:00
以前做过 aop+redis 锁 防止表单重复提交,但是也是基于 token 来做的,token 都不一样了 不是两次不同的请求吗?一个页面里面存了两个 token ?没看明白
|
9
Evilk 2020-08-27 17:45:42 +08:00
@lidlesseye11 同问
|
10
wysnylc 2020-08-27 17:53:26 +08:00
|
11
yangbonis 2020-08-27 18:55:01 +08:00 via iPhone
信息安全 重放攻击?
|
12
zjsxwc 2020-08-27 19:05:39 +08:00 via Android
get 请求不影响;
post 请求看业务,有些需求本来不就是幂等的(大部分 post 请求都是),有些需求天生就不能重复(比如需要短信验证码的场景,验证码用过之后里面失效了),有些需求业务上就需要判断是否重复发起(如果检查到重复发起忽略后续处理但返回成功就是幂等,如果检查到重复发起直接报错返回失败就不是幂等)。 |
13
Jooooooooo 2020-08-27 19:05:54 +08:00
前端拦住
不过业务上两次不同的请求为啥要防止 这个最终想问的是如何判断是两次有效请求还是一次? |
14
guagusi 2020-08-27 20:01:40 +08:00
以下单为例,1>用户进入下单页面先请求一个唯一的订单 token ; 2>用户点击下单后,带上 token 提交,下单按钮置灰不可点击; 3>后端校验 token 是否重复; 4>增加同一用户两次请求频率的限制,例如 1s 内多次下单;
|
15
leeg810312 2020-08-27 21:34:04 +08:00 via Android
问题改成误提交 2 次,怎样保证业务数据唯一性或最终一致性,这样比较准确?防君子只要前端控制,在提交后禁用提交按钮即可。防小人,就是阻挡重放攻击,那么上面很多人已经回答了。
|
16
oneisall8955 2020-08-27 22:15:33 +08:00 via Android
1.实现幂等性常见的方式有:悲观锁( for update )、乐观锁、唯一约束
2.几种方式,按照最优排序:乐观锁 > 唯一约束 > 悲观锁 摘抄自网络,我面试时候也是这么回答的 |
17
npe 2020-08-27 22:19:16 +08:00
幂等跟原子性、一致性感觉差不多。
|
18
laminux29 2020-08-27 22:37:16 +08:00 1
这事一定要和业务一起考虑。
举几个场景: 1.需要支持快速多次点击的场景:比如点外卖,或者淘宝下单,有时候需要快速多次点击增加数量按钮。 2.需要禁止快速多次点击的场景:比如提交订单按钮,按一次就够了。多按属于业务上的无效操作。 3.只允许慢速多次点击的场景:比如视频网站的发送弹幕按钮。 4.只允许慢速单次点击的场景:比如在线考试的多选题。 |
19
opengps 2020-08-27 22:37:16 +08:00
保存不成功,客户端的 requestid 不能重新 new
|
20
lihongming 2020-08-28 01:09:38 +08:00 via iPhone 1
要保证幂等性,你总得有一个唯一识别来区分不同的请求。所以你首先得定义唯一识别,比如订单可以用订单号(防止重复支付),帖子可以用内容(比如很多论坛程序不允许连发两个一模一样的帖子),什么都没有的可以用 token 等等。
如果真像楼主说的两次请求有不同的 token,那是后端设计的问题,前端只能用 js 控制一下重复提交,不可能完全禁止。 |
21
CantSee 2020-08-28 01:15:22 +08:00 via Android
token 唯一性
|
22
xuanbg 2020-08-28 08:34:18 +08:00 2
首先,这个不是幂等性问题。有 3 个办法可以解决这个问题:
1 、前端防抖,按钮点击后立即禁用,等接口返回后再视情况启用或跳转页面。 2 、后端限流,同一来源在一定时间间隔内只允许调用一次。这个方案的好处是通用,且可以顺便减轻接口被非法调用的压力。 3 、使用令牌,前端提交数据前先获取一个令牌,后端限制令牌只能使用一次。 |
23
Jammar 2020-08-28 09:18:29 +08:00
前端请求之前先获取一段唯一字符串,请求时带上,后端写入了就从缓存里删了
|
26
ksice 2020-08-28 18:40:01 +08:00
感觉防重复提交也可以维持幂等性
|
27
crclz 2020-08-29 08:21:20 +08:00
看可以使用幂等接口设计(局限)、ConcurrencyToken (例如实体的 updatedAt )、csrf-token (只能支撑非 spa 的场景
) or 客户端生成的 token 。 |
28
buhi 2020-08-29 09:48:33 +08:00
幂等性是后端保证的, 不是前端保证的
|