AntiForgery and JSON incompatible?

一个人想着一个人 提交于 2019-12-08 10:37:43

问题


I have been successfully using the AntiForgery option with Ajax in Orchard Modules for a while. Recently, I have been wanting to change from using the default ContentType = 'application/x-www-form-urlencoded; charset=UTF-8' to a JSON payload (ContentType='application/JSON').

As soon as I do this I get an exception thrown by ASP.NET 'A required anti-forgery token was not supplied or was invalid.'. OK, but how do I go about adding the __RequestVerificationToken while preserving JSON payload?

For reference, here is the code I'm using:

    var config = {
        url: url,
        type: "POST",
        data: data ,
        dataType: "json",
        contentType: "application/json; charset=utf-8"
    };
    $.ajax(config);

Controller (blows up with 'A required anti-forgery token was not supplied or was invalid.' before it gets here):

    [HttpPost]
    public ActionResult Update(ShoppingCartItemVM[] items)
    {
       // do stuff
    }

Is this a limitation of the Orchard AntiForgery wrapper or of the MVC AntiForgery functionality? Or am I being stupid (again)?


回答1:


Giscard is correct. I'll dig a bit deeper.

Note: Only the "post" results in orchard controller require the anti forgery token. So there is less of a requirement to remember that where using a "Get" in a request for json.

Often you will want to send more data than just the request token. In that case the 'data' object you send with your request must contain that __RequestVerificationToken value. In that case jQuery is useful for example:

var defaultPostValues = { __RequestVerificationToken:'@Html.AntiForgeryTokenValueOrchard()', id: 1, ..etc.. };
var myValues = { answers: [1,5,5,10] };
var data = $.extend({}, defaultPostValues, myValues); 

var config = {
    url: url,
    type: "POST",
    data: data ,
    dataType: "json",
    contentType: "application/json; charset=utf-8"
};
$.ajax(config);

The anti-forgery token can also be turned off per module definition (if I remember correctly?). Module.txt

Name: Polls
AntiForgery: false
Author: Matt
... removed for brevity 
Features:
    Polls
... etc

However I would recommend using the antiforgery if your calls are within Orchard's modules, and disabling if and only if your data is needed else where by external requests. But I would recommend WebAPI within Orchard for that case but that creates a whole new story and probably likely moves far out of scope.




回答2:


Maybe try this:

​data = {color: 'red', weight:'20lbs'};

// do some more work...

// Append the anti-forgery token to the POST values: 
data['__RequestVerificationToken'] = '@Html.AntiForgeryTokenValueOrchard()';

// Make the .ajax() call: 
var config = {
    url: url,
    type: "POST",
    data: data ,
    dataType: "json",
    contentType: "application/json; charset=utf-8"
};
$.ajax(config);

If you are forming the json somewhere other than a razor view, you can do the @Html.AntiForgeryTokenValueOrchard() inside a razor view and pass it to a javascript object or variable so you can add it to the json via javascript.

EDIT: In addition to the method Matthew posted, you can also append the anti-forgery token to the POST values right before you make the AJAX call without using .extend(). Example: http://jsfiddle.net/JC66L/.



来源:https://stackoverflow.com/questions/12504090/antiforgery-and-json-incompatible

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!