【问题标题】:Passing AntiForgeryToken in a JSON post request along wih JSON.stringify is not working在 JSON 发布请求中传递 AntiForgeryToken 以及 JSON.stringify 不起作用
【发布时间】:2017-08-24 15:50:54
【问题描述】:

我有以下 jQuery 代码,它使用 JSON.stringify 将数据发布到 ASP.NET MVC 控制器类。在没有引入 AntiForgeryToken 的情况下一切正常。现在,当我开始在代码库中实现 AntiForgeryToken 时,它不起作用并引发错误:所需的防伪表单字段“__RequestVerificationToken”不存在。

HTML

<form action="javascript: void(0)" id="frmMain">
    @Html.AntiForgeryToken()
    ....
</form>

jQuery 代码:

function saveDetails() {              
    var testViewModel = {};
    testViewModel.ArticleType = $("#SubType").val()
    testViewModel.PublishedDate = $("#publishDate").val();
    var token = $('#frmMain input[name=__RequestVerificationToken]').val();

    var languages = [];
    $.each($('#language').val(), function (index, value) {
        var languageContent = {};
        languageContent.Language = value;
        languageContent.Author = $("#author-" + value).val();
        languageContent.TeaserText = $("#teaser-" + value).val();
        languageContent.body = $("#content-" + value).val();
        languageContent.Title = $("#title-" + value).val();
        languages.push(languageContent);
    });
    testViewModel.LanguageContent = languages;
    testViewModel.Author = testViewModel.LanguageContent[0].Author;
    testViewModel.ArticleId = aId;

    $.ajax({
        type: "POST",
        url: "@Url.Action("SaveDetails", "Test")",
        data: JSON.stringify({ articleViewModel: articleViewModel, __RequestVerificationToken: token  }),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        cache: false,
        success: function (data) {
            var url = "@Url.Action("SiteDetails", "Test")";
            window.location.href = url + "?ArticleId=" + aId;
        }
    });
}

TestController.cs

[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult SaveDetails([Bind(Include = "ArticleId,PublishedDate,Author,ArticleType,LanguageContent")]TestObject testViewModel)
{
  if (!ModelState.IsValid)
  {
        return Json(new { success = false });
  }
}

任何人都可以通过提供解决此问题的指导来帮助我

【问题讨论】:

  • 删除 json 和 stringify 并按原样发布数据
  • 参考this answer。但是,您为具有这些 id 属性的集合生成表单控件这一事实表明您做错了。
  • 而且您使用 ajax 提交一个 for 然后重定向的事实是毫无意义的。只需正确生成视图(参考this answer 为集合生成表单控件,或this one 如果动态添加控件)并在 POST 方法中进行正常提交和重定向
  • 感谢斯蒂芬的解决方案。我同意您的观点,并且一定会实施您提供的链接中建议的方法。

标签: c# asp.net-mvc-5 csrf-protection antiforgerytoken


【解决方案1】:

我添加了另一个过滤器:

namespace TestDetails.Controllers
{
    [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"]);
        }
    }
}

TestController.cs

[HttpPost]
[ValidateHeaderAntiForgeryToken]
public JsonResult SaveDetails([Bind(Include = "ArticleId,PublishedDate,Author,ArticleType,LanguageContent")]TestObject testViewModel)
{
  if (!ModelState.IsValid)
  {
        return Json(new { success = false });
  }
}

function saveDetails() {              
    var testViewModel = {};
    testViewModel.ArticleType = $("#SubType").val()
    testViewModel.PublishedDate = $("#publishDate").val();
    var token = $('#frmMain input[name=__RequestVerificationToken]').val();

    var languages = [];
    $.each($('#language').val(), function (index, value) {
        var languageContent = {};
        languageContent.Language = value;
        languageContent.Author = $("#author-" + value).val();
        languageContent.TeaserText = $("#teaser-" + value).val();
        languageContent.body = $("#content-" + value).val();
        languageContent.Title = $("#title-" + value).val();
        languages.push(languageContent);
    });
    testViewModel.LanguageContent = languages;
    testViewModel.Author = testViewModel.LanguageContent[0].Author;
    testViewModel.ArticleId = aId;


    $.ajax({
        type: "POST",
        url: "@Url.Action("SaveDetails", "Test")",        
        headers: {
                "__RequestVerificationToken": token
        },
        data: JSON.stringify(testViewModel),
        cache: false,
        success: function (data) {
            var url = "@Url.Action("SiteDetails", "Test")";
            window.location.href = url + "?ArticleId=" + aId;
        }
    });
}

现在一切正常。

【讨论】:

    猜你喜欢
    • 2017-11-21
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    相关资源
    最近更新 更多