Is it possible/right to use multiple @Html.AntiForgeryToken() in 2 different forms in one page?

后端 未结 1 770
长情又很酷
长情又很酷 2020-12-28 20:44

I have been facing serious problem with @Html.AntiForgeryToken() . I have a register controller which had a create view to create/register new members. For that

相关标签:
1条回答
  • 2020-12-28 21:18

    Finally 8 hours of struggling gives me a solution.

    First things first, yes there is no harm to use 2 anti-forgery tokens in the page. And second there is no need to match the cookies with the providing token. Providing token will be always different and will be verified in the server.

    Anti-forgery token does not work if we use [HttpGet] action verbs.. Because in the validation process of anti-forgery the token is validated by retrieving of the Request.Form['__RequestVerificationToken'] value from the request. ref : Steven Sanderson's blog: prevent cross...

    Solution :

    My modifies controller:

    [HttpPost]
    
            [ValidateAntiForgeryToken(Salt = @ApplicationEnvironment.SALT)]
    //change the map route values to accept this parameters.
            public ActionResult username(string id, string __RequestVerificationToken) {
            string returnParam = __RequestVerificationToken;
    
            try {
                if (id == null || id.Length < 3)
                    return Json(returnParam, JsonRequestBehavior.AllowGet);
    
                var member = Membership.GetUser(id);
    
                if (member == null) {
                    //string userPattern = @"^([a-zA-Z])[a-zA-Z_-]*[\w_-]*[\S]$|^([a-zA-Z])[0-9_-]*[\S]$|^[a-zA-Z]*[\S]$";
                    string userPattern = "[A-Za-z][A-Za-z0-9._]{3,80}";
                    if (Regex.IsMatch(id, userPattern))
                        return Json(returnParam, JsonRequestBehavior.AllowGet);
                }
    
            } catch (Exception ex) {
                CustomErrorHandling.HandleErrorByEmail(ex, "Validate LogName()");
                return Json(returnParam, JsonRequestBehavior.AllowGet);
            }
            //found e false
            return Json(returnParam, JsonRequestBehavior.AllowGet);
        }
    

    My first Form in the same page:

    @using (Html.BeginForm("Create", "Register")) {
    
        @Html.AntiForgeryToken(ApplicationEnvironment.SALT)
    
        @Html.ValidationSummary(true)
        ....
    }
    

    My second Form in the same page:

    **<form id="validation">
        <!-- there is harm in using 2 anti-forgery tokens in one page-->
        @Html.AntiForgeryToken(ApplicationEnvironment.SALT)
        <input type="hidden" name="id" id="id" value="" />
    </form>**
    

    My jQuery to solve this thing:

     $("#LogName").blur(function () {
                var user = $("#LogName").val();
                var logValidate = "/Validation/username/";
                $("#validation #id").val(user);
                **var form = $("#validation").serialize(); // a form is very important to verify anti-forgery token and data must be send in a form.**
    
                var token = $('input[name=__RequestVerificationToken]').val();
    
                $.ajax({
                    **type: "POST", //method must be POST to validate anti-forgery token or else it won't work.**
                    dataType: "JSON",
                    url: logValidate,
                    data: form,
                    success: function (response) {
                        alert(response);
                    }
                });
            });
    
    0 讨论(0)
提交回复
热议问题