Ajax POST不存在__RequestVerificationToken

时间:2017-09-28 11:48:04

标签: jquery asp.net-mvc csrf-protection antiforgerytoken

我使用jQuery DataTales从MVC5请求POST URL并尝试添加防伪令牌。我已将它添加到标题和请求正文中,但仍然会收到500错误:"所需的防伪表单字段" __ RequestVerificationToken"不存在。"

表格:

<form id="my-units-form" action="@Url.Action("MyUnitsResults", "Provider")" class="form-horizontal criteria well well-sm">
    @Html.AntiForgeryToken()
    ....

JavaScript:

$userDt = $('#users-table')
    .DataTable({
        serverSide: true,
        ordering: false,
        searching: true,
        ajax: {
            "url": url,
            "type": "POST",
            'contentType': 'application/json',
            "dataType": "json",
            headers: { '__RequestVerificationToken': $('form input[name=__RequestVerificationToken]').val() },
            data: function (d) {
                d.__RequestVerificationToken= $('form input[name=__RequestVerificationToken]').val();

                return JSON.stringify(d);
            }
        },

Headers

Payload

1 个答案:

答案 0 :(得分:2)

如果您使用contentType: 'application/json对数据进行字符串化处理,则只将令牌添加到ajax标头中(不会从正文中读取)。

然后,您需要创建自定义FilterAttribute以从标题中读取值

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public sealed class ValidateHeaderAntiForgeryTokenAttribute : 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"]);
    }
}

并在您的控制器方法中,将[ValidateAntiForgeryToken]属性替换为[ValidateHeaderAntiForgeryToken]