[英]Validate Anti forgery key not working with ajax post
我嘗試在 ajax post 請求中使用驗證防偽令牌,但響應是沒有找到根元素。 我刪除了防偽令牌,它運行良好。
這是我的代碼:
function Save() {
let GroupName = GetElementValue("GroupName");
let GroupId = GetElementValue("GroupId");
var Group = {
__RequestVerificationToken: gettoken(),
GroupId: :1",
GroupName: "My Group Name"
};
if (IsFormValid("GroupForm")) {
AjaxPost("/Groups/AddGroup", Group).done(function () {
GetGroups();
});
}
}
function gettoken() {
var token = '@Html.AntiForgeryToken()';
token = $(token).val();
return token;
}
function AjaxPost(url, data) {
return $.ajax({
type: "post",
contentType: "application/json;charset=utf-8",
dataType: "json",
responseType: "json",
url: url,
data: JSON.stringify(data)
});
}
我也試過這個:
$.ajax({
type: "POST",
url: "/Groups/AddGroup",
data: {
__RequestVerificationToken: gettoken(),
GroupId: 1,
GroupName: "please work"
},
dataType: 'json',
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
});
這是后端:
[HttpPost]
[ValidateAntiForgeryToken]
public void AddGroup([FromBody] GroupView Group)
{
if (Group.GroupName.Trim().Length>0)
{
bool existed = _context.Groups.Any(x => x.GroupName.ToLower().TrimEnd().Equals(Group.GroupName.ToLower().TrimEnd()));
if (!existed)
{
Groups group = new Groups()
{
GroupName = Group.GroupName
};
_context.Groups.AddAsync(group);
_context.SaveChanges();
int? groupId = group.GroupId;
}
}
}
這是我的班級 GroupView
public class GroupView
{
public string GroupId { get; set; }
public string GroupName { get; set; }
}
我想使用正常發送帶有我的數據的串行令牌的方法,我怎樣才能使它工作? 任何幫助!
在ASP.NET Core中,您可以通過表單或標頭傳遞防偽令牌。 因此,我可以為您提供2種解決方案。
解決方案1.標頭
為了讓框架讀取頭,你需要配置令牌AntiforgeryOptions
並設置HeaderName
非null
值。 將此代碼添加到Startup.cs
//or if you omit this configuration
//HeaderName will be "RequestVerificationToken" by default
services.AddAntiforgery(options =>
{
options.HeaderName = "X-CSRF-TOKEN"; //may be any other valid header name
});
並在AJAX
傳遞防偽令牌
function Save() {
//..
//no need to set token value in group object
var Group = {
GroupId: "1",
GroupName: "My Group Name"
};
//..
}
function AjaxPost(url, data) {
return $.ajax({
type: "post",
contentType: "application/json;charset=utf-8",
dataType: "json",
responseType: "json",
headers: {
"X-CSRF-TOKEN": gettoken()
},
url: url,
data: JSON.stringify(data)
});
解決方案2.表格
您已經嘗試過通過表單傳遞令牌,但是沒有用。 為什么? 原因是IAntiforgeryTokenStore
的默認實現(用於從請求中讀取令牌)無法從json讀取反偽造令牌,而是將其讀取為表單數據。 如果要使其工作,則不要對請求數據進行stringify
處理,也不要從$.ajax
調用中刪除contentType
屬性。 JQuery將分別為您設置適當的內容類型並序列化數據。
//all other original code is unchanged, group needs to contain a token
function AjaxPost(url, data) {
return $.ajax({
type: "post",
dataType: "json",
responseType: "json",
url: url,
data: data
});
另外,在這種情況下,您還需要從操作參數中刪除[FromBody]
屬性,以使模型綁定程序正確綁定模型
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddGroup(GroupView group)
對於FromBody
,它將從application/json
綁定模型,但是CSRF
不會從正文讀取令牌。
最簡單的方法是,可以將標頭添加到RequestVerificationToken
。
Controller
[HttpPost("/Groups/AddGroup")]
[ValidateAntiForgeryToken]
public void AddGroup([FromBody] GroupView Group)
{
}
Client
<script type="text/javascript">
$(document).ready(function(){
var Group = {
__RequestVerificationToken: gettoken(),
GroupId: 1,
GroupName: "My Group Name"
};
AjaxPost("/Groups/AddGroup", Group).done(function () {
GetGroups();
});
});
function gettoken() {
var token = '@Html.AntiForgeryToken()';
token = $(token).val();
return token;
}
function AjaxPost(url, data) {
return $.ajax({
type: "post",
contentType: "application/json;charset=utf-8",
dataType: "json",
responseType: "json",
url: url,
headers: {
"RequestVerificationToken": gettoken()
},
data: JSON.stringify(data)
});
}
</script>
您將必須在VIEW內的表單中生成令牌,如下所示:
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm"
}))
{
@Html.AntiForgeryToken()
}
然后,您可以像這樣在Javascript中獲取令牌的值:
var form = $('#__AjaxAntiForgeryForm');
var token = $('input[name="__RequestVerificationToken"]', form).val();
最后,您可以像這樣通過AJAX將令牌發送給您的控制器:
$.ajax({
type: "POST",
url: "/Groups/AddGroup",
data: {
__RequestVerificationToken: token ,
GroupId: 1,
GroupName: "please work"
},
dataType: 'json',
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.