我的页面有...
@page "{candidateId:int}"
...和
@Html.AntiForgeryToken()
模特有......
public void OnGet(int candidateId)
{
}
public void OnPost(int candidateId)
{
}
GET工作正常。这是我的AJAX请求..
$.ajax({
type: "POST",
url: "/Skills/" + candidateId,
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: {
name: 'hi mum'
},
success: function (response) {
},
failure: function (response) {
alert(response);
}
});
浏览器收到无用的错误消息... 400 Bad Request。
我错过了什么?
答案 0 :(得分:14)
您收到400(错误请求)响应,因为框架期望RequestVerificationToken
作为已发布请求的一部分。框架使用此来防止可能的CSRF攻击。如果您的请求没有此信息,框架将返回400错误请求。您当前的代码没有发送它。
将代码更改为此
headers:
{
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
这将向请求标头添加一个带有键RequestVerificationToken
的新项,并且在进行调用时框架不应该抛出400响应。 (假设您的视图代码生成了__RequestVerificationToken
隐藏输入的隐藏输入)
通过将IAntiforgery
实现注入视图/页面并使用GetAndStoreTokens
方法,可以使代码更加健壮。
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Model.HttpContext).RequestToken;
}
}
并调用此GetAntiXsrfRequestToken
函数以获取javascript中的值
headers:
{
"RequestVerificationToken": '@GetAntiXsrfRequestToken()'
},
您可能还想使用PageModel的CandidateId
属性来创建网址。像这样的东西
url: "/Skills/@Model.CandidateId",
此外,您需要显式调用@Html.AntiForgeryToken()
方法以生成令牌输入。使用没有操作属性值的post方法的表单将为您生成隐藏的输入。
<form method="post">
<!-- your inputs-->
</form>