19

我的页面有...

@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。

我错过了什么?

4

1 回答 1

42

您将收到 400(错误请求)响应,因为框架希望将其RequestVerificationToken作为已发布请求的一部分。框架使用它来防止可能的 CSRF 攻击。如果您的请求没有此信息,框架将返回 400 bad request。您当前的代码未发送。

将代码更改为此

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。像这样的东西

url: "/Skills/@Model.CandidateId",

此外,您确实需要@Html.AntiForgeryToken()显式调用方法来生成令牌输入。拥有一个没有 action 属性值的带有 post 方法的表单将为您生成隐藏的输入。

<form method="post">
   <!-- your inputs-->
</form>
于 2018-01-22T01:24:02.803 回答