include antiforgerytoken in ajax post ASP.NET MVC

后端 未结 11 2276
感动是毒
感动是毒 2020-11-22 14:00

I am having trouble with the AntiForgeryToken with ajax. I\'m using ASP.NET MVC 3. I tried the solution in jQuery Ajax calls and the Html.AntiForgeryToken(). Using that solu

相关标签:
11条回答
  • 2020-11-22 14:41

    it is so simple! when you use @Html.AntiForgeryToken() in your html code it means that server has signed this page and each request that is sent to server from this particular page has a sign that is prevented to send a fake request by hackers. so for this page to be authenticated by the server you should go through two steps:

    1.send a parameter named __RequestVerificationToken and to gets its value use codes below:

    <script type="text/javascript">
        function gettoken() {
            var token = '@Html.AntiForgeryToken()';
            token = $(token).val();
            return token;
       }
    </script>
    

    for example take an ajax call

    $.ajax({
        type: "POST",
        url: "/Account/Login",
        data: {
            __RequestVerificationToken: gettoken(),
            uname: uname,
            pass: pass
        },
        dataType: 'json',
        contentType: 'application/x-www-form-urlencoded; charset=utf-8',
        success: successFu,
    });
    

    and step 2 just decorate your action method by [ValidateAntiForgeryToken]

    0 讨论(0)
  • 2020-11-22 14:42

    You have incorrectly specified the contentType to application/json.

    Here's an example of how this might work.

    Controller:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Index(string someValue)
        {
            return Json(new { someValue = someValue });
        }
    }
    

    View:

    @using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
    {
        @Html.AntiForgeryToken()
    }
    
    <div id="myDiv" data-url="@Url.Action("Index", "Home")">
        Click me to send an AJAX request to a controller action
        decorated with the [ValidateAntiForgeryToken] attribute
    </div>
    
    <script type="text/javascript">
        $('#myDiv').submit(function () {
            var form = $('#__AjaxAntiForgeryForm');
            var token = $('input[name="__RequestVerificationToken"]', form).val();
            $.ajax({
                url: $(this).data('url'),
                type: 'POST',
                data: { 
                    __RequestVerificationToken: token, 
                    someValue: 'some value' 
                },
                success: function (result) {
                    alert(result.someValue);
                }
            });
            return false;
        });
    </script>
    
    0 讨论(0)
  • 2020-11-22 14:42

    Another (less javascriptish) approach, that I did, goes something like this:

    First, an Html helper

    public static MvcHtmlString AntiForgeryTokenForAjaxPost(this HtmlHelper helper)
    {
        var antiForgeryInputTag = helper.AntiForgeryToken().ToString();
        // Above gets the following: <input name="__RequestVerificationToken" type="hidden" value="PnQE7R0MIBBAzC7SqtVvwrJpGbRvPgzWHo5dSyoSaZoabRjf9pCyzjujYBU_qKDJmwIOiPRDwBV1TNVdXFVgzAvN9_l2yt9-nf4Owif0qIDz7WRAmydVPIm6_pmJAI--wvvFQO7g0VvoFArFtAR2v6Ch1wmXCZ89v0-lNOGZLZc1" />
        var removedStart = antiForgeryInputTag.Replace(@"<input name=""__RequestVerificationToken"" type=""hidden"" value=""", "");
        var tokenValue = removedStart.Replace(@""" />", "");
        if (antiForgeryInputTag == removedStart || removedStart == tokenValue)
            throw new InvalidOperationException("Oops! The Html.AntiForgeryToken() method seems to return something I did not expect.");
        return new MvcHtmlString(string.Format(@"{0}:""{1}""", "__RequestVerificationToken", tokenValue));
    }
    

    that will return a string

    __RequestVerificationToken:"P5g2D8vRyE3aBn7qQKfVVVAsQc853s-naENvpUAPZLipuw0pa_ffBf9cINzFgIRPwsf7Ykjt46ttJy5ox5r3mzpqvmgNYdnKc1125jphQV0NnM5nGFtcXXqoY3RpusTH_WcHPzH4S4l1PmB8Uu7ubZBftqFdxCLC5n-xT0fHcAY1"
    

    so we can use it like this

    $(function () {
        $("#submit-list").click(function () {
            $.ajax({
                url: '@Url.Action("SortDataSourceLibraries")',
                data: { items: $(".sortable").sortable('toArray'), @Html.AntiForgeryTokenForAjaxPost() },
                type: 'post',
                traditional: true
            });
        });
    });
    

    And it seems to work!

    0 讨论(0)
  • 2020-11-22 14:42

    I know this is an old question. But I will add my answer anyway, might help someone like me.

    If you dont want to process the result from the controller's post action, like calling the LoggOff method of Accounts controller, you could do as the following version of @DarinDimitrov 's answer:

    @using (Html.BeginForm("LoggOff", "Accounts", FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
    {
        @Html.AntiForgeryToken()
    }
    
    <!-- this could be a button -->
    <a href="#" id="ajaxSubmit">Submit</a>
    
    <script type="text/javascript">
        $('#ajaxSubmit').click(function () {
    
            $('#__AjaxAntiForgeryForm').submit();
    
            return false;
        });
    </script>
    
    0 讨论(0)
  • 2020-11-22 14:42

    In Account controller:

        // POST: /Account/SendVerificationCodeSMS
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public JsonResult SendVerificationCodeSMS(string PhoneNumber)
        {
            return Json(PhoneNumber);
        }
    

    In View:

    $.ajax(
    {
        url: "/Account/SendVerificationCodeSMS",
        method: "POST",
        contentType: 'application/x-www-form-urlencoded; charset=utf-8',
        dataType: "json",
        data: {
            PhoneNumber: $('[name="PhoneNumber"]').val(),
            __RequestVerificationToken: $('[name="__RequestVerificationToken"]').val()
        },
        success: function (data, textStatus, jqXHR) {
            if (textStatus == "success") {
                alert(data);
                // Do something on page
            }
            else {
                // Do something on page
            }
        },
        error: function (jqXHR, textStatus, errorThrown) {
            console.log(textStatus);
            console.log(jqXHR.status);
            console.log(jqXHR.statusText);
            console.log(jqXHR.responseText);
        }
    });
    

    It is important to set contentType to 'application/x-www-form-urlencoded; charset=utf-8' or just omit contentTypefrom the object ...

    0 讨论(0)
提交回复
热议问题