验证防伪密钥不适用于 ajax post
Validate Anti forgery key not working with ajax post
我尝试将验证防伪令牌与 ajax post 请求一起使用,但响应是找不到根元素。
我删除了它完美运行的防伪令牌。
这是我的代码:
javascript;
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;
}
}
}
这是我的 Class GroupView
public class GroupView
{
public string GroupId { get; set; }
public string GroupName { get; set; }
}
我想使用我正常发送串行令牌和我的数据的方法,
我怎样才能让它工作?
任何帮助!
在 ASP.NET Core 中,您可以通过表单或 headers 传递防伪令牌。所以我可以为您推荐 2 个解决方案。
解决方案一. Headers
为了让框架从 headers 读取令牌,您需要配置 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)
});
方案二.表格
您已经尝试通过表单传递令牌,但没有成功。为什么?原因是 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
不会从 body 读取令牌。
对于最简单的方法,您可以添加 header 和 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>
这是我的代码: javascript;
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;
}
}
}
这是我的 Class GroupView
public class GroupView
{
public string GroupId { get; set; }
public string GroupName { get; set; }
}
我想使用我正常发送串行令牌和我的数据的方法, 我怎样才能让它工作? 任何帮助!
在 ASP.NET Core 中,您可以通过表单或 headers 传递防伪令牌。所以我可以为您推荐 2 个解决方案。
解决方案一. Headers
为了让框架从 headers 读取令牌,您需要配置 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)
});
方案二.表格
您已经尝试通过表单传递令牌,但没有成功。为什么?原因是 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
不会从 body 读取令牌。
对于最简单的方法,您可以添加 header 和 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>