在JSON帖子请求中提供AntiForgeryToken

时间:2016-03-25 12:06:56

标签: c# jquery asp.net json asp.net-mvc

我查了一下:

How can i supply an AntiForgeryToken when posting JSON data using $.ajax?

how can i use AntiForgeryToken with JSON post in mvc 4

http://forums.asp.net/t/1561850.aspx?How+can+i+supply+a+antiforgerytoken+when+posting+JSON+data+using+ajax+

并尝试了所提到的一切。可悲的是,没有提出任何建议。

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

var headers = {};

headers['__RequestVerificationToken'] = token;

var data = serializeData(token);

$.ajax(
{
    cache: false,
    async: false,
    type: 'POST'
    url: url
    data: data,
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    headers: headers,
    success: function (result) {
    },
    error: function () {
        e.stopPropagation();
    }
});

function serializeData(token) {   
var data = {
    __RequestVerificationToken: token,
    MyJsonData : JSON.stringify(myFormData),
};

return data;   
}

我总是得到RequestVerificationToken不存在的例外情况。

但是,如果我从ajax调用中排除contentType参数,它会成功验证令牌,但是控制器中的MyJsonData为空,并且它带有异常:

  

{“从类型'System.String'到类型的参数转换   'MyJsonData'失败了   因为没有类型转换器可以在这些类型之间进行转换。“}

我也尝试将令牌作为请求标头的一部分发送,但这也不起作用。

2 个答案:

答案 0 :(得分:1)

我建议AJAX Form submit。该库将使用ajax对其数据进行字符串化并发送,就好像它是常规表单提交一样。我已将它与验证令牌一起使用,没有任何问题。

选项:Full options list here 例如:

options = {
    url: "url",
    type: "post",
    success: handler,
    error: handler,
    complete: handler
}

这将在致电后立即提交表格。

$("#myFormId").ajaxSubmit(options)

这将等到单击表单提交按钮并改为使用ajax提交。

$("#myFormId").ajaxForm(options) 

答案 1 :(得分:1)

根据这个Approach,我认为使用自定义属性将是一个更好的解决方案。因此,不要使用数据序列化令牌,而是让此属性完成工作。

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    public sealed 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] 
[ValidateJsonAntiForgeryToken]
public ActionResult DoSomething(Foo foo) {
    //Do something
}