张贴到Razor页面时出现400错误请求

Ian*_*ton 8 asp.net-mvc razor razor-pages

我的页面有......

@page "{candidateId:int}"
Run Code Online (Sandbox Code Playgroud)

......和

@Html.AntiForgeryToken()
Run Code Online (Sandbox Code Playgroud)

模特有......

public void OnGet(int candidateId)
{

}

public void OnPost(int candidateId)
{

}
Run Code Online (Sandbox Code Playgroud)

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);
    }
});
Run Code Online (Sandbox Code Playgroud)

浏览器收到无用的错误消息... 400 Bad Request.

我错过了什么?

Shy*_*yju 18

您正在获得400(错误请求)响应,因为框架期望RequestVerificationToken作为已发布请求的一部分.框架使用此来防止可能的CSRF攻击.如果您的请求没有此信息,框架将返回400错误请求.您当前的代码没有发送它.

将代码更改为此

headers:
{
    "RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
},
Run Code Online (Sandbox Code Playgroud)

这将RequestVerificationToken在请求标头中添加一个带有键的新项,并且在进行调用时框架不应该抛出400响应.(假设您的视图代码为隐藏输入生成__RequestVerificationToken隐藏输入)

通过将IAntiforgery实现注入视图/页面并使用该GetAndStoreTokens方法,可以使代码更加健壮.

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
    return Xsrf.GetAndStoreTokens(Model.HttpContext).RequestToken;
}
}
Run Code Online (Sandbox Code Playgroud)

并调用此GetAntiXsrfRequestToken函数以获取javascript中的值

headers:
{
    "RequestVerificationToken": '@GetAntiXsrfRequestToken()'
},
Run Code Online (Sandbox Code Playgroud)

您可能还想使用PageModel的CandidateId属性来创建URL.像这样的东西

url: "/Skills/@Model.CandidateId",
Run Code Online (Sandbox Code Playgroud)

此外,您需要@Html.AntiForgeryToken()显式调用方法以生成令牌输入.使用没有操作属性值的post方法的表单将为您生成隐藏的输入.

<form method="post">
   <!-- your inputs-->
</form>
Run Code Online (Sandbox Code Playgroud)

  • 有同样的问题,我的表单中缺少 @H​​tml.AntiForgeryToken() (4认同)
  • @mxmissile 您可以通过使用“[IgnoreAntiforgeryToken(Order = 1001)]”装饰您的 PageModel 来忽略防伪令牌的验证。在此处查看更多信息:https://www.learnrazorpages.com/security/request-verification#opting-out (4认同)
  • “您收到 400(错误请求)响应,因为框架期望 RequestVerificationToken 作为发布请求的一部分。” 我可以在文档中的哪里找到此特定信息?请发布链接。 (3认同)
  • 如果您需要接受来自外部站点的 POST 怎么办?我们不能包含防伪令牌的站点。 (2认同)