ASP.NET Core 在 json 发布请求正文中传递 antiforgerytoken

Posted

技术标签:

【中文标题】ASP.NET Core 在 json 发布请求正文中传递 antiforgerytoken【英文标题】:ASP.NET Core pass antiforgerytoken in json post request body 【发布时间】:2017-11-21 22:39:24 【问题描述】:

嗯,我有一个通过表单 tagHelper 呈现的表单。所以它包含了防伪令牌的特殊隐藏。

我正在尝试发送以下 ajax 请求:

var data = JSON.stringify(feedbackForm.serializeArray().reduce((res, item) => 
       res[item.name] = item.value;
       return res; , ));
 // data example: '"Description":"some description", "__RequestVerificationToken":"CfDJ8F9f8kTKlVNEsnTxejQIJ__pRCl2CuZTQDVAY2216J7GgHWGDC0XUMPc0FKHpr_K5uhz8Kx0VeHDkIPdQ3V0Xur9oLE2u_bpfXuVss6AWX3BVh0WbwfQriaibOrf_yvEuIYZV-jHU_G-AHPD91cKz_QE7MVmeLVgTum80yTb8biGctMtJcU67Wp7ZgN86yMuew"'` 
  $.ajax(
         type: "POST",
         url: '@Url.Action("Feedback", "Profile", new Area = "")',
         contentType: "application/json; charset=utf-8",
         data: data,
         dataType: "json"
  );

到看起来像这样的控制器操作:

 [HttpPost]
 [AllowAnonymous]
 [ValidateAntiForgeryToken]
 public async Task<IActionResult> Feedback([FromBody]FeedbackViewModel vm)
 
    ...
 

所以发布的数据包含防伪令牌的密钥,但是请求仍然没有通过防伪验证并失败并出现错误。如果我从控制器中删除防伪验证属性,它就会完美地工作。

为什么它不检查请求正文中的令牌 - 这是设计使然,还是某种问题?

【问题讨论】:

Enable Antiforgery Token with ASP.NET Core and JQuery的可能重复 好吧,我不想将实现更改为标头,我想找出为什么它不适用于请求正文。 我最近一直在做类似的工作,IIRC,你需要标题和数据元素匹配。 @silent_coder 我相信你在找this 我没有时间完全验证它,但是我认为当您将数据作为 json(“application/json”)发送到 CSRF 中间件时,它无法验证令牌无法反序列化 json 并从那里获取令牌。但是,如果您的 ajax 帖子将数据作为 url 编码形式(“application/x-www-form-urlencoded”)发送,这与常规帖子基本相同。这就是为什么在 json 情况下您需要将令牌添加为标头 【参考方案1】:

你能尝试像下面这样实现吗?

data["__RequestVerificationToken"] = $('[name=__RequestVerificationToken]').val();
var data = JSON.stringify(feedbackForm.serializeArray().reduce((res, item) => 
   res[item.name] = item.value;
   return res; , ));

$.ajax(
    url: '@Url.Action("Feedback", "Profile", new Area = "")',
    contentType: "application/json"
    type: 'POST',
    context: document.body,
    data: data,
    success: function()  refresh(); 
);

【讨论】:

在我的情况下,它需要以 json 格式发送,因为我正在发布 BLOB,并且它大于允许的 urlencoded 数据请求 @silent_coder 我已经用 json 内容类型更新了我的答案。【参考方案2】:

您可以像下面这样传递“标题”。

var data = JSON.stringify(feedbackForm.serializeArray().reduce((res, item) => res[item.name] = item.value;return res; , ));
$.ajax(
     url: '@Url.Action("Feedback", "Profile", new Area = "")',
     type: "POST",
     dataType: "json",
     headers: "__RequestVerificationToken":$('[name=__RequestVerificationToken]').val(),         
     contentType: "application/json; charset=utf-8",
     data: data);

参考:https://api.jquery.com/jQuery.ajax/

【讨论】:

欢迎来到 ***!请编辑您的答案以包括对您的代码的解释,以及它与其他解决方案的不同之处。这将使您的答案更有可能被认为有用并被赞成:)

以上是关于ASP.NET Core 在 json 发布请求正文中传递 antiforgerytoken的主要内容,如果未能解决你的问题,请参考以下文章

每个请求的 ASP.NET Core API JSON 序列化程序设置

在 ASP.NET Core 中使用 IHttpClientFactory 发出 HTTP 请求

asp.net core 3 Web API !发送 json 到 POST 动作

ASP.NET Core中返回 json 数据首字母大小写问题

使用 Vue 和 ASP.NET Core DTO 模型的 JSON 对象的 JSON 序列化问题

asp.net core webapi Post接收不到ajax请求数据