防止一键式 Laravel 多次提交

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50421591/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 17:43:39  来源:igfitidea点击:

Prevent Multiple Submitting in one button laravel

phplaravel

提问by Abdan Syakuro

Before i make this question i use javascript method to prevent multiple submit on my blade template. But i know it's client side that still possible to get attack by.

在我提出这个问题之前,我使用 javascript 方法来防止在我的刀片模板上多次提交。但我知道客户端仍然可能受到攻击。

This is my javascript code

这是我的 javascript 代码

<script>
    function submitForm(btn) {
        // disable the button
        btn.disabled = true;
        // submit the form    
        btn.form.submit();
    }
</script>

<input id="submitButton" type="button" value="Submit" onclick="submitForm(this);" />

my question is, is there another way to prevent without client side in laravel?

我的问题是,是否有另一种方法可以防止在 laravel 中没有客户端?

回答by Saurabh

The most straightforward way to guarantee the uniqueness of a form submission (In the sense of stopping someone mashing submit twice) is to generate a random token and storing it in a session AND a hidden field.

保证表单提交唯一性的最直接方法(在阻止某人两次提交两次的意义上)是生成一个随机令牌并将其存储在会话和隐藏字段中。

If it doesn't match, reject the form, if it does match, accept the form and nuke the session key.

如果不匹配,则拒绝该表单,如果匹配,则接受该表单并取消会话密钥。

OR

或者

Force Laravel to regenerate a new session token after each time a token is verified correctly. (Easy Way Out)

每次正确验证令牌后,强制 Laravel 重新生成新的会话令牌。(简单的办法)

To achieve this, create a new function tokensMatch()in app/Http/Middleware/VerfiyCsrfToken.php(which will overwrite the inherited one). Something like this:

要实现这一点,请tokensMatch()app/Http/Middleware/VerfiyCsrfToken.php(将覆盖继承的)中创建一个新函数。像这样的东西:

protected function tokensMatch($request)
{
    $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');

    if (!$token && $header = $request->header('X-XSRF-TOKEN')) {
        $token = $this->encrypter->decrypt($header);
    }

    $tokensMatch = hash_equals($request->session()->token(), $token);

    if($tokensMatch) $request->session()->regenerateToken();

    return $tokensMatch;
}

In case you validate the form and the validation fails, the old data will be passed back to the form. So you need to make sure not to pass back the old token by adding _tokento the $dontFlasharray in app/Exceptions/Handler.php

如果您验证表单并且验证失败,旧数据将被传递回表单。所以你需要确保不要通过添加_token$dontFlash数组中来传回旧令牌app/Exceptions/Handler.php

protected $dontFlash = ['password', 'password_confirmation', '_token'];

protected $dontFlash = ['password', 'password_confirmation', '_token'];