Bohn Bohn - 2 months ago 18
C# Question

How to prevent sending login request multiple times from a form

In my login form I have a method like this:

[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
public async Task<ActionResult> Login(LoginModel model, string returnUrl)
{

var result = await _applicationSignInManager.PasswordSignInAsyncResponse(someParamshereToPass);

// ...
}


Problem is while it is taking time to do the login check, user can double click on the submit button and call this method again and although user has now been authenticated it will try to create another token for him which causes the crash below:


The provided anti-forgery token was meant for a different claims-based
user than the current user.


I did lookup answers for preventing double click on forms, couldn't get them to work and most of them their solution was to disable the button! well then how to enable it if they typed their password wrong!! and some were
Ajax
that I don't know how to use.

So ideally I am looking for a server-side solution to this, if not, then a
JS
solution. if not then ok an
Ajax
solution!

Win Win
Answer

You can disable the button after it is clicked.

Only issue is if you use ASP.Net MVC client-side validation, you want to disable it only after client-side validation is successful. Otherwise, button will be disabled forever if user clicks on the button without entering anything.

@using (Html.BeginForm("Login", "Account",
   new { ReturnUrl = ViewBag.ReturnUrl },
   FormMethod.Post, new {  role = "form", autocomplete = "off" }))
{
   @Html.AntiForgeryToken()
   ...
   <div class="form-group">
     <button id="btnSubmit" type="submit" value="Sign In" 
         class="btn btn-primary btn-block">Sign In</button>
   </div>
}

<script type="text/javascript">
    $(function () {    
        $("form").data("validator").settings.submitHandler = function (form) {
            $("#btnSubmit").html("<i class=\"fa fa-spinner fa-pulse\"></i> Signing In...").prop('disabled', true);
            form.submit();
        };
    });
</script>

enter image description here