【发布时间】:2019-10-31 13:01:53
【问题描述】:
我有一个createOrder 请求,目前有点慢(大约 3 - 4 秒)。我正在尝试使用 CSRF 令牌或自定义令牌来防止重复提交表单。
对于这种情况,我正在使用带有文件驱动程序的代客服务......所以这很可能是问题所在,但我尚未将此代码推送到生产服务器,因为它没有按预期工作。
它是这样工作的:
令牌被添加到会话和提交表单中的隐藏
"custom_token"字段中。表单已提交,我们会在中间件或控制器本身中进行快速比较。
if(! hash_equals($request->session()->get('custom_token'), $request->custom_token)){
flash()->error('Order placed twice');
return redirect('/checkout/thank-you');
}
$request->session()->put('custom_token', Str::random(40));
- 如果它们不匹配,我们会进行快速重定向(Flash 消息目前仅用于调试)。
如果我从控制器中删除主要的 create orde 调用(即慢速位),则上述方法有效,但其中包括 hash_equals 始终返回 true。
所以我的问题是:
- 这可能是由于会话文件驱动程序更新缓慢造成的吗?
- 当然,如果是这种情况,即使在生产环境中仍然存在发生这种情况的风险。
- 有没有更好的方法可以防止在后端重复提交表单?
【问题讨论】:
-
为什么
!在if(! hash_equals中? -
如果哈希不相等,抛出错误?
-
好的,现在代码是有意义的,但是,不相等并不一定意味着请求被放置了两次。任何人都可以使用检查元素调整 custom_token。
-
我假设一旦使用 CSRF 令牌,它就不能再次播放,Laravel 会将它自己列入黑名单。但我希望你在你的路由上启用了 VerifyCsrfToken 中间件。
-
如果
hash_equals一次为真,我们接下来要做的就是用新的custom_token重写。这与其说是有人入侵了系统,不如说是为了确保普通用户在快速提交时单击提交按钮或按回浏览器并以这种方式重新提交时不会提交两次。