web-dev-qa-db-ja.com

RazorページにPOSTするときの400 Bad Request

私のページは...

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

何が欠けていますか?

11
Ian Warburton

フレームワークはポストされたリクエストの一部としてRequestVerificationTokenを想定しているため、400(不正なリクエスト)レスポンスを取得しています。フレームワークはこれを使用して、起こりうる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を作成することもできます。このようなもの

_url: "/Skills/@Model.CandidateId",
_

また、トークン入力を生成するには、@Html.AntiForgeryToken()メソッドを明示的に呼び出す必要があります。 action属性値のないpostメソッドを持つフォームがあると、非表示の入力が生成されます。

_<form method="post">
   <!-- your inputs-->
</form>
_
18
Shyju