为了账号安全,请及时绑定邮箱和手机立即绑定

使用$ .ajax发布JSON数据时,如何提供AntiForgeryToken?

/ 猿问

使用$ .ajax发布JSON数据时,如何提供AntiForgeryToken?

慕雪6442864 2019-09-21 15:35:39

我正在使用下面这篇文章的代码:


首先,我将使用控制器操作的正确值填充数组变量。


使用下面的代码,我认为只需将以下行添加到JavaScript代码中,应该非常简单:


data["__RequestVerificationToken"] = $('[name=__RequestVerificationToken]').val();

该<%= Html.AntiForgeryToken() %>是在其正确的位置,动作有[ValidateAntiForgeryToken]


但是我的控制器动作一直在说:“无效的伪造令牌”


我在这里做错了什么?


data["fiscalyear"] = fiscalyear;

data["subgeography"] = $(list).parent().find('input[name=subGeography]').val();

data["territories"] = new Array();


$(items).each(function() {

    data["territories"].push($(this).find('input[name=territory]').val());

});


    if (url != null) {

        $.ajax(

        {

            dataType: 'JSON',

            contentType: 'application/json; charset=utf-8',

            url: url,

            type: 'POST',

            context: document.body,

            data: JSON.stringify(data),

            success: function() { refresh(); }

        });

    }


查看完整描述

3 回答

?
波斯汪

你不需要因为MVC 4. ValidationHttpRequestWrapper解决方案根据这个链接。


将令牌放在标题中。

创建一个过滤器。

将属性放在您的方法上。

这是我的解决方案:


var token = $('input[name="__RequestVerificationToken"]').val();

var headers = {};

headers['__RequestVerificationToken'] = token;

$.ajax({

    type: 'POST',

    url: '/MyTestMethod',

    contentType: 'application/json; charset=utf-8',

    headers: headers,

    data: JSON.stringify({

        Test: 'test'

    }),

    dataType: "json",

    success: function () {},

    error: function (xhr) {}

});



[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]

public class ValidateJsonAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter

{

    public void OnAuthorization(AuthorizationContext filterContext)

    {

        if (filterContext == null)

        {

            throw new ArgumentNullException("filterContext");

        }


        var httpContext = filterContext.HttpContext;

        var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];

        AntiForgery.Validate(cookie != null ? cookie.Value : null, httpContext.Request.Headers["__RequestVerificationToken"]);

    }

}



[HttpPost]

[AllowAnonymous]

[ValidateJsonAntiForgeryToken]

public async Task<JsonResult> MyTestMethod(string Test)

{

    return Json(true);

}


查看完整回答
反对 回复 2019-09-21
?
慕姐829404

出问题的是,应该处理此请求并用[ValidateAntiForgeryToken]期望标记的控制器动作期望__RequestVerificationToken与该请求一起被称为POST 的参数。


您正在使用的参数中没有POST,JSON.stringify(data)它会将表单转换为JSON表示形式,因此会引发异常。


所以我可以在这里看到两个可能的解决方案:


数字1:用于x-www-form-urlencoded代替JSON发送您的请求参数:


data["__RequestVerificationToken"] = $('[name=__RequestVerificationToken]').val();

data["fiscalyear"] = fiscalyear;

// ... other data if necessary


$.ajax({

    url: url,

    type: 'POST',

    context: document.body,

    data: data,

    success: function() { refresh(); }

});

数字2:将请求分为两个参数:


data["fiscalyear"] = fiscalyear;

// ... other data if necessary

var token = $('[name=__RequestVerificationToken]').val();


$.ajax({

    url: url,

    type: 'POST',

    context: document.body,

    data: { __RequestVerificationToken: token, jsonRequest: JSON.stringify(data) },

    success: function() { refresh(); }

});

因此,在所有情况下,您都需要发布该__RequestVerificationToken值。


查看完整回答
反对 回复 2019-09-21
?
守着一只汪

我只是在当前项目中实现了这个实际问题。我对所有需要经过身份验证的用户的Ajax POST都执行了此操作。


首先,我决定挂断我的jQuery Ajax调用,这样我就不必再重复一遍了。这个JavaScript代码段可确保所有ajax(发布)调用都会将我的请求验证令牌添加到请求中。注意:.NET框架使用名称__RequestVerificationToken,因此我可以使用标准的Anti-CSRF功能,如下所示。


$(document).ready(function () {

    securityToken = $('[name=__RequestVerificationToken]').val();

    $('body').bind('ajaxSend', function (elm, xhr, s) {

        if (s.type == 'POST' && typeof securityToken != 'undefined') {

            if (s.data.length > 0) {

                s.data += "&__RequestVerificationToken=" + encodeURIComponent(securityToken);

            }

            else {

                s.data = "__RequestVerificationToken=" + encodeURIComponent(securityToken);

            }

        }

    });

});

在需要令牌可用于以上JavaScript代码的视图中,只需使用公共HTML-Helper。您基本上可以在任何位置添加此代码。我将其放在if(Request.IsAuthenticated)语句中:


@Html.AntiForgeryToken() // You can provide a string as salt when needed which needs to match the one on the controller

在您的控制器中,只需使用标准的ASP.NET MVC反CSRF机制。我是这样做的(尽管我实际上用了盐)。


[HttpPost]

[Authorize]

[ValidateAntiForgeryToken]

public JsonResult SomeMethod(string param)

{

    // Do something

    return Json(true);

}

使用Firebug或类似工具,您可以轻松地看到POST请求现在如何附加了__RequestVerificationToken参数。


查看完整回答
反对 回复 2019-09-21

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信