【问题标题】:AntiForgery and JSON incompatible?AntiForgery 和 JSON 不兼容?
【发布时间】:2012-09-19 23:06:07
【问题描述】:

我已经在 Orchard Modules 中成功使用 Ajax 的 AntiForgery 选项有一段时间了。最近,我一直想改变使用默认的 ContentType = 'application/x-www-form-urlencoded; charset=UTF-8' 到 JSON 有效负载 (ContentType='application/JSON')。

一旦我这样做,我就会得到 ASP.NET 抛出的异常“未提供所需的防伪令牌或无效。”。好的,但是如何在保留 JSON 有效负载的同时添加 __RequestVerificationToken?

作为参考,这是我正在使用的代码:

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

控制器(在到达此处之前显示“未提供所需的防伪令牌或无效。”):

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

这是 Orchard AntiForgery 包装器或 MVC AntiForgery 功能的限制吗?还是我(再次)愚蠢?

【问题讨论】:

  • 为什么需要发送 JSON?要么你正在与你的 Orchard 服务器交谈,它会很好地理解 post(包括绑定复杂的数组参数,就像你在那里拥有的那样),要么它是一个外部服务,它不会关心防伪。
  • Json 不是必需的。但是我在这方面反复绊倒,需要知道是我自己还是我不知道的一些限制。正如马修和吉斯卡所言,是我!感谢您的帮助。

标签: asp.net-mvc json orchardcms


【解决方案1】:

季斯卡是正确的。我会深入一点。

注意:只有果园管理员的“post”结果需要防伪令牌。因此,无需记住在 json 请求中使用“Get”的位置。

通常您需要发送的数据不仅仅是请求令牌。在这种情况下,您随请求发送的“数据”对象必须包含该 __RequestVerificationToken 值。在这种情况下,jQuery 很有用,例如:

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);

也可以根据模块定义关闭防伪令牌(如果我没记错的话?)。 模块.txt

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

但是,如果您的调用在 Orchard 的模块内,我建议使用防伪,并且仅当外部请求需要您的数据时才禁用。但我会推荐 Orchard 中的 WebAPI 用于这种情况,但这会创建一个全新的故事,并且可能会超出范围。

【讨论】:

  • 您可以按模块关闭它,也可以按控制器操作关闭它。我的示例未经测试,但我认为即使已经为 data var 分配了一些值,它也可以工作(请参阅此处,了解如何将新的键/值对分配给现有的 javascript 对象:stackoverflow.com/a/4071599/239185)。
  • 您和 Giscard 都正确地推测出问题出在 Json 数据格式上。谢谢。
【解决方案2】:

不妨试试这个:

​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);

如果您在剃刀视图以外的地方形成 json,您可以在剃刀视图中执行 @Html.AntiForgeryTokenValueOrchard() 并将其传递给 javascript 对象或变量,以便您可以通过 javascript 将其添加到 json。

编辑:除了 Matthew 发布的方法之外,您还可以在不使用 .extend() 进行 AJAX 调用之前将防伪标记附加到 POST 值。示例:http://jsfiddle.net/JC66L/

【讨论】:

    猜你喜欢
    • 2014-03-12
    • 1970-01-01
    • 2013-10-06
    • 2020-11-15
    • 2023-03-24
    • 2011-05-24
    • 2013-01-26
    • 2019-09-22
    • 2019-05-23
    相关资源
    最近更新 更多